Java大作业设计报告.docx
- 文档编号:28636706
- 上传时间:2023-07-19
- 格式:DOCX
- 页数:12
- 大小:1.05MB
Java大作业设计报告.docx
《Java大作业设计报告.docx》由会员分享,可在线阅读,更多相关《Java大作业设计报告.docx(12页珍藏版)》请在冰豆网上搜索。
Java大作业设计报告
《Java程序设计》大作业设计报告
设计名称多人聊天室
组员姓名
学生班级
设计时间2013.12.15
设计成绩
一、问题描述及设计思路
设计多人聊天程序,能进行多人实时聊天,其中服务器为PC端,客户端为安卓端。
在服务器上,不断监听来自客户端的接入请求,对于接入的客户端加入线程池,同时为之开启独立线程,等待从该客户端发来的信息,再转发给其他客户端。
在客户端上,首先布局简单的安卓界面,开启客户端并且登录后,设置button按钮监听想服务器发送信息请求,同时开启独立线程接收来自服务器的信息(即来自其他客户端的信息)。
二、详细设计过程
服务器开发
1.首先,导入了我们完成服务器端所要完成的各种类:
importjava.io.*;
importjava.awt.*;
importjavax.swing.*;
import.*;
importjava.util.*;
importjava.util.concurrent.ExecutorService;
importjava.util.concurrent.Executors;
由导入的包和类可以知道我们组是采用了多线程和Socket通信完成主要功能,辅助以GUI界面进行美化。
2.在Server类里面的私有成员函数里,有以下定义:
privatestaticfinalintport=9999;//端口号
privateJTextAreajta=newJTextArea();
privateExecutorServicemExecutorService;//线程池
privatestaticArrayList
Filefile=newFile("MessageRecord.txt");//创建信息记录文本,记录每个客户端的链接信息
Filefile1=newFile("TalkingRecord.txt");//创建聊天记录文本,把客户的聊天记录记录下来
我们定义了port的端口号默认为9999,还构造了线程池以便接下来为多线程运行做准备,
同时创建了一个广义的ArrayList
创建了两个file类的文件,分别用于记录客户端的链接信息和保存客户端的聊天记录。
3.采用一个构造函数,把大部分的任务在里面完成,代码如下:
publicServer(){
mExecutorService=Executors.newCachedThreadPool();//创建线程池
setLayout(newBorderLayout());
add(newJScrollPane(jta),BorderLayout.CENTER);
setTitle("MultiThreadServer");
setSize(500,300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
try{//创建与客户端的链接
ServerSocketserverSocket=newServerSocket(port);//建立套接字
jta.append("MultiThreadServerstartedat"+newDate()+'\n');//此句可有可无,输出一个日期
intclientNo=1;//客户端的数目
while(true){//连接客户端
Socketsocket=serverSocket.accept();//链接客户端
vector.add(socket);
mExecutorService.execute(newThread(newHandleAClient(socket)));
clientNo++;
PrintWriteroutput=newPrintWriter(file);
jta.append("Startingthreadforclient"+clientNo+"at"
+newDate()+'\n');//追加连接的客户端的创建日期
InetAddressinetAddress=socket.getInetAddress();//获取客户端的IP地址
jta.append("Client"+clientNo+"`shostnameis"
+inetAddress.getHostName()+'\n');//追加客户端的主机名字并显示
output.println("Client"+clientNo+"`shostnameis"
+inetAddress.getHostName());//将客户端的主机名字写进文本
jta.append("Client"+clientNo+"`sIPaddressis"
+inetAddress.getHostAddress()+'\n');//追加客户端的IP地址并显示
output.println("Client"+clientNo+"`sIPaddressis"
+inetAddress.getHostAddress());//将客户端的IP地址写进文本
output.close();
}
}catch(IOExceptionex){
System.err.println(ex);
}
首先是创建一个空的线程池,便于以后的客户端连接进来,每个客户端都是一个独立的线程,互不干扰。
接下来则是采用GUI组件进行简单的界面设计,在try-catch块里完成主要功能。
首先,采用ServerSocketserverSocket=newServerSocket(port);建立套接字,一旦建立成功,则在服务器端的界面上会出现创建的日期信息。
又使用Socketsocket=serverSocket.accept();连接客户端,采用while语句不断监听客户端连接,收到请求后,则在服务器端显示客户端的信息,如连接到服务器的时间,客户端的主机名称和IP地址,这些信息会被写进txt文本进行保存。
mExecutorService.execute(newThread(newHandleAClient(socket)));则是向线程池中添加线程,这里使用了一个内部类HandleAClient用于处理服务器和单独一个客户端之间的问题。
请看下面的继续解析。
4.采用一个内部类HandAClient完成一个客户端和服务器之前互相传输信息的功能,代码如下:
privateclassHandleAClientimplementsRunnable{//用一个内部类来处理一个客户端的问题
privateSocketsocket;
privatePrintWriterpw;
privateBufferedReaderbr;
privateStringmsg;
publicHandleAClient(Socketsocket){
this.socket=socket;
}
@Override
publicvoidrun(){
try{
br=newBufferedReader(newInputStreamReader(
socket.getInputStream(),"utf-8"));
while(true){
msg=br.readLine();
if(msg.trim().equals("exit")){
vector.remove(socket);
br.close();
pw.close();
msg="user:
"+this.socket.getInetAddress()+":
"
+"exit\ntotalclient:
"+vector.size()+"\n";
socket.close();
sendToClient();
}else{
msg=socket.getInetAddress()+":
"+msg+"\n";
sendToClient();
}
jta.append(msg);
}
}catch(IOExceptione){
System.err.println(e);
}
}
privatevoidsendToClient()throwsIOException{
for(Socketclient:
vector){
pw=newPrintWriter(client.getOutputStream(),true);
pw.println(msg);
}
}
}
在这个内部类中,先是定义了两个流对象pw和br用于从客户端读取信息和将信息发送到其他的客户端。
首先,用br获取流对象,再用msg保存读到的信息,同时在里面还定义了另外一个函数sendToClient(),用于把信息发送给客户端,在发送信息是,服务端还要进行判断,通过ArrayList类对象Vector,里面每一个元素为客户端的socket,进行判断:
如果获取到的某个信息是来源于客户端A,则发送时客户端A暂时关闭,把A的信息发送到其他的所有客户端,这样会避免在客户端上自己发出的信息显示两次的问题。
同时,服务端把客户端的信息保存为记录文本txt文件。
客户端开发
开发步骤:
1.新建一个android应用程序
2.在布局文件中添加两个button控件标签,和两个文本框,并未其设置属性和值
3.在Activity中,声明控件变量并根据id获得控件对象
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_talk);
buttonIn=(Button)findViewById(R.id.buttonIn);
buttonSend=(Button)findViewById(R.id.buttonSend);
//showthemessages
text01=(EditText)findViewById(R.id.text01);
//inputthemessage
text02=(EditText)findViewById(R.id.text02);
4.以匿名内部类方式监听button
//thebuttonoflogin
buttonIn.setOnClickListener(newOnClickListener(){
publicvoidonClick(Viewv){
try{
//connecttoserver
s=newSocket(IP,PORT);
//inputStreamincludesinbr
br=newBufferedReader(newInputStreamReader(s
.getInputStream()));
//osistheoutputStream
os=s.getOutputStream();
}catch(Exceptione){
//handleexception
Log.e(DEBUG_TAG,e.toString());
}
}
});
//thebuttonofsend
buttonSend.setOnClickListener(newOnClickListener(){
publicvoidonClick(Viewv){
try{
//gettheinformationfromthetext02
Stringstr=text02.getText().toString();
//showtheinformationontext01
text01.setText(str);
os.write((str+"\n").getBytes("utf-8"));
}catch(Exceptione){
//handleexception
Log.e(DEBUG_TAG,e.toString());
}
}
});
5.登陆后,开启线程监听来自服务器的信息
privateRunnablemyRunnable=newRunnable(){
publicvoidrun(){
//monitortheinformationfromtheservercontinually
while(true){
try{
if((message=br.readLine())!
=null){
message+="\n";
mHandler.sendMessage(mHandler.obtainMessage());
}
}catch(Exceptione){
Log.e(DEBUG_TAG,e.toString());
}
}
}
};
开启异步处理函数:
HandlermHandler=newHandler(){
publicvoidhandleMessage(Messagemsg){
super.handleMessage(msg);
try{
//showtheinformationfromtheserver
text01.append(message);
}catch(Exceptione){
Log.e(DEBUG_TAG,e.toString());
}
}
};
三、结论及体会
此次大作业,是我们团队对新知识应用很好的一次的尝试。
此次我们团队四人分成两组,分别写服务器和客户端。
期间,我们一共敲出三份代码。
首先单客户端通信的软件,这个程序难度比较小。
另外还敲了比较复杂的安卓UDP通信程序,有用户名自定义跟头像选择,但是因为在安卓Activity间用intent转换时没有找出其中的bug,所以暂时性放弃那份代码。
这份代码是第三份相对第二份来说比较简单。
通过此次合作,让我们团队深刻地了解到,对于多而泛的知识学习,我们更应该强调合作精神,分工细化,这样能更有效地进行学习,因此我们也专门成立android学习小组。
四、附录(图表、关键代码)
服务器界面:
一旦服务器端运行,那么在服务器上就会显示这次服务器运行时的准确时间。
一旦连接到客户端,就会在服务器的界面上不断显示信息。
具体请看客户端代码报告。
客户端界面:
客户端登录:
客户端发送消息:
其他客户端接入
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Java 作业 设计 报告