聊天室系统设计报告.docx
- 文档编号:8373743
- 上传时间:2023-01-30
- 格式:DOCX
- 页数:34
- 大小:583.12KB
聊天室系统设计报告.docx
《聊天室系统设计报告.docx》由会员分享,可在线阅读,更多相关《聊天室系统设计报告.docx(34页珍藏版)》请在冰豆网上搜索。
聊天室系统设计报告
青岛科技大学
操作系统课程设计
学生班级计算机132班
学生学号1308010204
学生姓名王永远
______年___月___日
设计题目:
聊天室系统
一、设计目的及要求
1.1设计目的
通过该聊天室系统,掌握网络编程的概念及基于网络的C/S模式软件系统开发,掌握基于TCP协议的Socket编程,掌握Java的多线程机制。
1.2设计要求:
实现多个用户之间类似于QQ的聊天程序,有聊天界面,多用户之间既可以实现群聊,也可以单独聊天。
二、技术背景
2.1网络编程
就是用来实现网络互连的不同计算机上运行的程序间可以进行数据交换。
2.2网络通信
(1)IP地址:
网络中设备的标识,不易记忆,可用主机名
要想让网络中的计算机能够互相通信,必须为每台计算机指定一个标识号,通过这个标识号来指定要接受数据的计算机和识别发送的计算机,在TCP/IP协议中,这个标识号就是IP地址。
(2)端口号:
用于标识进程的逻辑地址
物理端口网卡口
逻辑端口我们指的就是逻辑端口
A:
每个网络程序都会至少有一个逻辑端口
B:
用于标识进程的逻辑地址,不同进程的标识
C:
有效端口:
0~65535,其中0~1024系统使用或保留端口。
(3)传输协议:
通信的规则,常见的有UDP,TCP
UDP:
将数据源和目的封装成数据包中,不需要建立连接;每个数据报的大小在限制在64k;因无连接,是不可靠协议;不需要建立连接,速度快。
TCP:
建立连接,形成传输数据的通道;在连接中进行大数据量传输;通过三次握手完成连接,是可靠协议;必须建立连接,效率会稍低。
2.3Socket
(1)Socket套接字
网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的标识符套接字。
(2)Socket原理机制
A:
通信的两端都有Socket。
B:
网络通信其实就是Socket间的通信。
C:
数据在两个Socket间通过IO传输。
2.4TCP传输
(1)客户端思路
A建立客户端的Socket服务,并明确要连接的服务器。
B如果连接建立成功,就表明,已经建立了数据传输的通道.就可以在该通道通过IO进行数据的读取和写入.该通道称为Socket流,Socket流中既有读取流,也有写入流.
C通过Socket对象的方法,可以获取这两个流
D通过流的对象可以对数据进行传输
E如果传输数据完毕,关闭资源
(2)服务器端思路
A建立服务器端的socket服务,需要一个端口
B服务端没有直接流的操作,而是通过accept方法获取客户端对象,在通过获取到的客户端对象的流和客户端进行通信
C通过客户端的获取流对象的方法,读取数据或者写入数据
D如果服务完成,需要关闭客户端,然后关闭服务器,但是,一般会关闭客户端,不会关闭服务器,因为服务端是一直提供服务的
2.5Java的多线程机制
进程:
每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程。
线程:
同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小。
多进程是指操作系统能同时运行多个任务(程序),多线程是指在同一程序中有多个顺序流在执行。
在java中,每次程序运行至少启动2个线程。
一个是main线程,一个是垃圾收集线程。
因为每当使用java命令执行一个类的时候,实际上都会启动一个JVM,启动JVM实际上就是在操作系统中启动了一个进程。
在java中所有的线程都是同时启动的,至于什么时候,哪个先执行,完全看谁先得到CPU的资源。
三、需求分析
实现聊天的功能,采用Java Socket编程,服务器与客户端采用了TCP/IP连接方式,在设计聊天方案时,可将所有信息发往服务器端,再由服务器进行处理,服务器端是所有信息的中心。
3.1客户端
3.1.1登录
用户需要填写用户名、服务器地址、端口号才可以进入聊天室与在线用户聊天,此外,服务器地址默认是本机地址,端口号默认是5000。
用户名可以中文,英文字母或标点符号,服务器地址必须是符合点分十进制的合法地址,端口号可以修改,但服务器端程序内默认端口号也必须修改。
该聊天室不需要注册,直接登录即可聊天,退出后,系统不保留用户任何信息。
若新登录用户与在线用户的用户名重名,则系统会自动修改用户名。
格式为:
用户名+“_客户端线程ID”。
3.1.2多人聊天
每个在线用户都可以发送聊天信息,服务器端会一直监听,并把每一个在线用户发送的聊天信息转发到每一个客户端。
聊天室的聊天信息格式为:
用户名时间(yyyy-MM-ddHH:
mm:
ss)
聊天信息
3.1.3单人聊天
用户可以选择某一个在线用户实现单人聊天,该聊天信息不会在聊天室显示,只有单聊的两个人能够看到。
单人聊天的聊天信息格式为:
用户名时间(yyyy-MM-ddHH:
mm)
聊天信息
3.2服务器端
服务器端主要处理客户端的请求,包括用户的登录,发送多人聊天信息,退出聊天室,单人聊天请求,发送单人聊天信息,并且随时更新在线用户列表。
四、总体设计
4.1设计思想流程图
4.2设计思想分析
首先启动服务器,它会建立一个专门用于接收客户端连接请求的“倾听Socket”,然后等待客户的连接请求。
当用户登录输入信息后,与服务器建立Socket连接,服务器端的“倾听Socket”收到连接请求后,会接受连接请求,并生成一个服务器端socket,专门负责与此客户端socket的通信。
一旦连接请求成功,客户端将信息及请求通过本方socket的输出流发送给服务器端相应的socket,服务端则通过服务器端Socket的输入流接受客户端传输过来的信息及请求,分析是何请求,然后根据请求类型,进行相应的处理(如登录、私聊等)。
服务器端也可以根据需要,通过socket的输出流发送信息和请求给客户端。
客户端和服务器端都可以通过关闭本方的socket而结束一次通信过程。
对于客户端的各种请求,实际上都是通过在客户端发往服务器的各种字符流区分的,具体的方法就是在消息的内部添加特殊字符串,从而实现服务器对消息请求的识别。
比如对于登陆信息,消息中添加的内容就是“@login”,而对于私聊中的消息,消息中添加的内容就是“@single”,其他的同理都添加了相应内容。
当然,对于客户端来说,这些都是透明的,用户的操作并没有受到任何影响。
在服务器端,消息被检测分析后,变回根据具体的目的进行处理,比如是私聊消息,服务器便会根据其内部添加的信息,向目标端转发该条消息,当目标端接收到连接请求后,会主动建立一个私聊窗口,从而实现私聊。
服务器端需要能同时接受多个用户的请求,为了实现这一点,一般使用多线程机制来处理,对每一个客户端连接通信,服务器端都有一个线程专门负责处理。
对于客户端的各种请求,内部添加的信息分别如下:
●@clientThread客户端线程启动
messages.add(clientThread.getId()+"@clientThread");
客户端线程ID
●@login登录客户端
username+"@login"+getThreadID()+"@login"
用户名+客户端线程ID
●@userlist用户列表
serverThread.users.get(newInteger(threadID))+"@userlist"+threadID+"@userlist"
用户名+客户端线程ID
●@chat群聊
username+"@chat"+getThreadID()+"@chat"+mess+"@chat"
用户名+客户端线程ID+聊天信息
●@serverexit服务器退出
serverThread.messages+"@serverexit"
●@single单聊
client.username+"@single"+client.getThreadID()+"@single"+(int)client.clientuserid.get(index)+"@single"+mess+"@single";
用户名+客户端线程ID+客户端线程ID+聊天信息
●@exit退出群聊
username+"@exit"+getThreadID()+"@exit"
用户名+客户端线程ID
五、详细设计
5.1客户端设计
5.1.1登录界面
5.1.2聊天室界面
5.1.3单人聊天界面
5.2服务器端设计
六、系统测试
6.1登录测试
6.1.1用户名为英文字母
6.1.2用户名为中文
6.1.3用户名为标点符号
6.1.4多个用户有重名
6.1.5服务器地址不合法
6.1.6端口号不合法
6.1.7服务器未开启
6.2群发消息测试
6.3私聊测试
6.4用户列表显示测试
无论已经登录用户的退出,还是新用户成功登录,用户列表显示部分都能正确显示。
七、心得体会
这段时间通过不断的修改,我终于把聊天室系统完成了,虽然它只有简单的聊天功能,但通过它,我不但巩固了以前学的知识,而且学到了许多在课堂中学不到的知识。
通过这次课程设计,我更坚定了理论与实际相结合是十分重要的想法,即使一个人读了再多的技术图书,但没有相关的实践经验,那么他也不会真正地掌握一门技术。
只有把理论知识与实践相结合,才会深入的了解并提高自己的独立思考能力。
通过这次的课程设计,我将自己所学的Java语言得到了实际的应用,在完成的过程中也遇到了许多困难,但通过不断地查阅资料,最终还是解决了,在这个过程中,我学会了独立思考,同时也让我明白完成一件事情要不断开阔视野,拓展知识面,解放自己的思维。
总之,在完成课程设计的过程中,我学会了如何克服开发中遇到的技术困难,学会了独立面对并解决问题。
八、参考资料
叶核亚JAVA程序设计实用教程(第2版)电子工业出版社
朱福喜,路迟JAVA语言与面向对象程序设计武汉大学出版社
沈文炎Java高级编程机械工业出版社
九、程序清单
(1)Client.java
publicclassClientextendsThread{
publicSocketc_socket;//套接字
privateClient_chatFramec_chatFrame;//聊天室聊天界面
privateClient_enterFramec_enterFrame;//客户端登录界面
privateClient_singleFramec_singleFrame;//单人聊天界面
publicDataInputStreamdis=null;//IO输入
publicDataOutputStreamdos=null;//IO输出
privatebooleanflag_exit=false;//客户端未启动标记
privateintthreadID;//聊天室客户端线程标记
publicMap
publicList
publicList
publicStringusername=null;//用户名
publicStringchat_re;//通道内相关信息
//getter,setter方法
publicClient_chatFramegetC_chatFrame(){
returnc_chatFrame;
}
publicClient_singleFramegetC_singlFrame(){
returnc_singleFrame;
}
publicvoidsetC_singlFrame(Client_singleFramec_singlFrame){
this.c_singleFrame=c_singlFrame;
}
publicvoidsetC_chatFrame(Client_chatFramec_chatFrame){
this.c_chatFrame=c_chatFrame;
}
publicClient_enterFramegetC_enterFrame(){
returnc_enterFrame;
}
publicvoidsetC_enterFrame(Client_enterFramec_enterFrame){
this.c_enterFrame=c_enterFrame;
}
publicintgetThreadID(){
returnthreadID;
}
publicvoidsetThreadID(intthreadID){
this.threadID=threadID;
}
//客户端构造函数
publicClient(){
c_singleFrames=newHashMap
username_online=newArrayList
clientuserid=newArrayList
//signlechatuse=newArrayList
}
//main方法,设置进入时登录界面
publicstaticvoidmain(String[]args){
Clientclient=newClient();
Client_enterFramec_enterFrame=newClient_enterFrame(client);
client.setC_enterFrame(c_enterFrame);
c_enterFrame.setVisible(true);
}
//登录客户端
publicStringlogin(Stringusername,StringhostIp,StringhostPort){
this.username=username;//用户名
Stringlogin_mess=null;//错误信息或true
try{
c_socket=newSocket(hostIp,Integer.parseInt(hostPort));
}catch(NumberFormatExceptione){
login_mess="连接的服务器端口号port为整数,取值范围为:
1024 returnlogin_mess; }catch(UnknownHostExceptione){ login_mess="主机地址错误"; returnlogin_mess; }catch(IOExceptione){ login_mess="连接服务器失败,请稍后再试"; returnlogin_mess; } return"true"; } //创建一个客户端聊天界面,启动一个线程 publicvoidshowChatFrame(Stringusername){ getDataInit(); c_chatFrame=newClient_chatFrame(this,username); c_chatFrame.setVisible(true); flag_exit=true;//客户端已启动 this.start();//启动线程 } //初始化,建立连接通道 privatevoidgetDataInit(){ try{ dis=newDataInputStream(c_socket.getInputStream()); dos=newDataOutputStream(c_socket.getOutputStream()); }catch(IOExceptione){ e.printStackTrace(); } } //该类声明为Thread的子类,重写Thread类的run方法 publicvoidrun(){ while(flag_exit){//客户端已启动 try{ //readUTF(): 读入一个已使用UTF-8修改版格式编码的字符串。 chat_re=dis.readUTF(); }catch(IOExceptione){ flag_exit=false; if(! chat_re.contains("@serverexit")){ chat_re=null; } } if(chat_re! =null){ if(chat_re.contains("@clientThread")){ intlocal=chat_re.indexOf("@clientThread"); setThreadID(Integer.parseInt(chat_re.substring(0,local)));//启动客户端线程,设置ThreadID try{ dos.writeUTF(username+"@login"+getThreadID()+"@login"); }catch(IOExceptione){ e.printStackTrace(); } }else{ if(chat_re.contains("@userlist")){ c_chatFrame.setDisUsers(chat_re); }else{ if(chat_re.contains("@chat")){ c_chatFrame.setDisMess(chat_re); }else{ if(chat_re.contains("@serverexit")){ c_chatFrame.closeClient(); }else{ if(chat_re.contains("@single")){ c_chatFrame.setSingleFrame(chat_re); } } } } } } } } //发送聊天信息 publicvoidtransMess(Stringmess){ try{ dos.writeUTF(username+"@chat"+getThreadID()+"@chat"+mess+"@chat"); }catch(IOExceptione){ e.printStackTrace(); } } //聊天室中退出聊天 publicvoidexitChat(){ try{ dos.writeUTF(username+"@exit"+getThreadID()+"@exit"); flag_exit=false; System.exit(0); }catch(IOExceptione){ e.printStackTrace(); } } //登录之前退出 publicvoidexitLogin(){ System.exit(0); } //服务器关闭,退出聊天室客户端,在Client_chatFrame中调用 publicvoidexitClient(){ flag_exit=false; System.exit(0); } } (2)WinCenter.java publicclassWinCenter{ publicstaticvoidcenter(Windowwin){ Toolkittkit=Toolkit.getDefaultToolkit();//使用系统工具包 DimensionsSize=tkit.getScreenSize();//屏幕尺寸 DimensionwSize=win.getSize();//窗体尺寸 if(wSize.height>sSize.height){ wSize.height=sSize.height; } if(wSize.width>sSize.width){ wSize.width=sSize.width; } win.setLocation((sSize.width-wSize.width)/2,(sSize.height-wSize.height)/2);//窗体居屏幕中央 } } (3)Server.java publicclassServer{ privateServerFrameserverFrame; privateServerThreadserverThread; publicServerFramegetServerFrame(){ returnserverFrame; } publicvoidsetServerFrame(ServerFrameserverFrame){ this.serverFrame=serverFrame; } publicServer(){} //启动服务器线程 publicvoidstartServer(){ try{ serverThread=newServerThread(serverFrame); }catch(Exceptione){ System.exit(0); } serverThread.setFlag_exit(true); serverThread.start(); } //停止服务器线程 publicvoidstopServer(){ synchronized(serverThread.messages){//同步代码块: synchronize
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 聊天室 系统 设计 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)