java实现聊天系统计算机网络课程设计报告

上传人:ph****6 文档编号:70311992 上传时间:2022-04-06 格式:DOC 页数:17 大小:98KB
返回 下载 相关 举报
java实现聊天系统计算机网络课程设计报告_第1页
第1页 / 共17页
java实现聊天系统计算机网络课程设计报告_第2页
第2页 / 共17页
java实现聊天系统计算机网络课程设计报告_第3页
第3页 / 共17页
点击查看更多>>
资源描述
- 计算机网络课程设计报告 学生学 号 班 级 指导教师 设计时间目录第一章 系统描述1.1设计目的31.2系统设计任务 31.3系统设计分析31.4系统功能分析4第二章 功能模块构造2.1模块划分52.2模块构造图52.1模块功能5第三章 模块算法实现3.1 效劳器实现63.2 客户端实现9第四章 运行结果13第五章 课程设计总结17第六章 附录6.1 参考文献196.2 源代码19第一章 系统描述1.1设计目的1学习网络编程的知识,掌握网络编程的方法。2进一步掌握编程思想与编程技巧,做到模块化程序设计,3. 强化语言学习,尤其是Java的图形界面与多线程,需反复练习,熟练掌握。1.2系统设计任务聊天室软件的设计与开发:根本要求可以完成群聊、私人聊天,实时发送和显示聊天信息,完成好友列表;进一步要求带表情,附件发送,聊天信息的加密传送,设置黑等。学习通信编程Socket接口编程,使用TCP或UDP接口完成信息传送,利用多线程技术实现效劳器端的多个TCP连接的建立。1.3系统设计分析一实现网络聊天室编程,关键在于Socket通信,程序的功能都是在Socket的根底上一层一层增加的。实现Socket通信的根本方法为以下4个步骤。(1) 在客户端与效劳器端创立相应的ServerSockot/Socket实例。(2) 翻开连接到Socket的输入输出流(3) 利用输入输出流,按照一定的协议TCP协议对Socket进展读写操作(4) 关闭输入输出流和Socket我们要实现的功能都是在第3步对Socket的输入输出流做相应的操作ServerSocket(port)Socket socket= ServerSocket.accept() 接收连接CloseOutputStream InputStreamServer通信过程Socket(host,port)与效劳器建立连接CloseOutputStream InputStreamClient二 因为是多客户端,所以必须用线程进展控制,不同的处理线程为不同的客户效劳,主线程只负责循环等待,处理线程负责网络连接,承受客户输入的信息,再做相应的处理。1.4系统功能分析本系统可以通过网络进展聊天,采用客户端效劳器模式,所以程序简介清晰易懂,而且用户都是在客户端进展活动,方便对用户的管理,也使得程序运行与过失简单起来。采用了多线程技术,可以做到多人同时在线,提高了系统的性能,增强了系统的实用性。有简单的客户端界面,方便用户使用。采用的是TCP协议,这是可靠的,稳定的协议,这样不会丧失任何包,也就不会丧失任何信息。本系统实现的功能有:1. 用户名字登录2. 用户之间的群聊3. 用户之间的私聊4. 动态刷新并显示好友列表5. 显示在线人数6. 效劳器可以显示用户在线状态7. 能够退出处理8. 用户上下线提醒第二章 功能模块构造2.1 模块划分 效劳器: Server类模块,ServerHanderson模块,sendallclient模块,sendclientlist模块客户端:Client类模块, ServiceFrame窗口界面模块ServerHander模块2.2 模块构造图ServerHander模块Server模块ServerHander模块通信过程建立连接ServiceFrame模块Client模块2.3 模块功能效劳器:1. Server类模块:与客户端建立连接,通过套接字获得名字,在控制端显示提示信息2. ServerHander模块:提供线程管理,实现多用户的管理。针对每一个用户发过来的消息,进展相应处理,再转发给客户。3. Sendallclient模块:给每个用户发送消息。4. Sendclientlist模块:每当有用户上线,更新每个用户的用户列表。客户端:1. Client类模块:与效劳端建立连接,用户登录,实现消息的群聊,私聊,用户列表的更新等功能。2. ServiceFrame窗口界面模块:客户端窗口界面,实现用户友好,方便用户使用,在窗口上有消息显示,用户列表,在线人数等视图信息。第三章 模块算法实现3.1 效劳器实现1. Server类模块:创立ServerSocket,在指定端口监听,当有用户登录,承受套接字输入流,显示其登录信息,调用ServerHander线程进展管理。public Server(int port) throws IOE*ceptionServerSocket server=new ServerSocket(port);while(true)Socket conn=server.accept(); /接收客户端套接字DataInputStream in =newDataInputStream(conn.getInputStream();String who=in.readUTF();System.out.print(Client+(ip:+conn.getInetAddress()+)+who+ 进入!+n);ServerHander=new ServerHander(who,conn);.start();2.Sendallclient模块: 把msg消息发送给每一个用户。其中allclients是ServerHander的枚举类型,可以指向每一个用户。protectedstaticvoid sendallclient(String msg) synchronized (clientlist)Enumeration allclients=clientlist.elements();while(allclients.hasMoreElements()ServerHander serh=(ServerHander)allclients.ne*tElement();tryserh.out.writeUTF(msg);serh.out.flush();catch(IOE*ception e*c)serh.interrupt();3.Sendclientlist模块:更新用户列表,当有新用户上线时,对以前的用户的好友列表,加上这个新用户名字,对于这个新用户,加上所有用户的名字。实现方法是在名字信息后面加上$关键字,这样客户端接收到这个关键字时,做相应处理。publicstaticsynchronizedvoid sendclientlist()for(int j=0;jclientlist.size();j+)ServerHander allclients1=clientlist.elementAt(j);if(j=clientlist.size()-1) /假设是新增用户,把vector中的所有用户都发送过去for(int i = 0;iclientlist.size();i+) ServerHander allclients2=clientlist.elementAt(i);try allclients1.out.writeUTF(allclients2.who+$); allclients1.out.flush(); catch(IOE*ception e*c) allclients1.interrupt(); else /老用户,只增加新来的用户 ServerHander allclients3=clientlist.lastElement();try allclients1.out.writeUTF(allclients3.who+$); allclients1.out.flush(); catch(IOE*ception e*c) allclients1.interrupt(); 4.ServerHander模块: 关键模块,与客户端进展消息的交互,相互加关键字,解密关键字,做到上下线提醒,群聊,私聊等功能。创立ServerHander的Vector对象,可以方便用户管理,Vector对象是可变数组,而且支持线程同步,适合在网络编程中使用。对用户发送过来的消息通过关键字进展解析,前面的字符串为发送的消息,后面的字符串为发送对象,假设发送给所有人,则直接发送,假设发送给*个人,则在发送的消息后面再加上关键字,让客户端去解析。有用户下线,发送下线消息,通过下线关键字,可以在客户端更新用户列表。class ServerHander e*tends ThreadSocket socket;DataInputStream in;DataOutputStream out;String who;protectedstatic Vectorclientlist=newVector() ; /把用户线程放入可变对象数组public ServerHander(String name,Socket socket) throws IOE*ceptionthis.who = name;this.socket = socket;in =new DataInputStream(new BufferedInputStream(socket.getInputStream();out =new DataOutputStream(new BufferedOutputStream(socket.getOutputStream();publicvoid run()tryclientlist.addElement(this); /VECTOR中增加新线程sendallclient(who+ 上线);sendclientlist(); /为每一个客户端更新在线用户while(true) String msg=in.readUTF();int inde* = msg.lastInde*Of(); /对客户端发过来的信息做相应的处理 String str = msg.substring(inde*+1,msg.length(); /取得发送对象和发送的消息 msg=msg.substring(0,inde*);if(str.equals(所有人)=false) sendallclient(who+ 对+str+ 说: +msg+); /不是发给所有人则增添标记 elsesendallclient(who+ 对所有人 说: +msg); catch(IOE*ception e)System.out.println(error);finallyclientlist.removeElement(this);System.out.print(Client +(ip:+socket.getInetAddress()+)+who+ 退出!+n);sendallclient(who+ 下线);trysocket.close();catch(IOE*ception e*)System.out.println(clsing);3.2 客户端实现1.ServerFrame窗口界面模块:有一个消息显示文本区域,消息发送框,发送按钮,好友列表下拉框,一条标签用来显示在线人数,文本区域添加在JscrollPane上,这样,无论消息有多长,多宽,都能显示出来,如果没添加的话,消息一多,就显示不出了,这个小细节,很多人都没注意。classServiceFramee*tends Frame JTe*tArea showAT; JTe*tField sendFD; oBo* friendlist; utton but; JLabel showCount;JScrollPanete*tAreaScrollPane; JPanel te*tFieldPanel = new JPanel();public ServiceFrame (String winname)super(winname); /继承父类的名字setSize(500,400);te*tFieldPanel.setLayout(new FlowLayout(0,10,10);showAT = new JTe*tArea(400,400);showAT.setEditable(false);te*tAreaScrollPane = newJScrollPane(showAT);add(te*tAreaScrollPane, BorderLayout.CENTER);add(te*tFieldPanel, BorderLayout.SOUTH);friendlist = new oBo*();friendlist.addItem(所有人);te*tFieldPanel.add(friendlist);sendFD = new JTe*tField(20);te*tFieldPanel.add(sendFD);but = new utton(发送);but.setMnemonic(KeyEvent.VK_ENTER);te*tFieldPanel.add(but);showCount = new JLabel(在线人数:1);te*tFieldPanel.add(showCount);show();按钮监听事件:当按下按钮,把发送文本框的消息再加上当前选择的发送对象写入输出流,中间用关键字隔开,在效劳端方便解析。class ActListener implements ActionListener Client client; ServiceFrame sframe;public ActListener(Client c,ServiceFrame sf)client=c;sframe=sf; publicvoid actionPerformed(ActionEvent e) /发送信息,并以作为私聊标记client.send(sframe.sendFD.getTe*t().trim()+sframe.friendlist.getSelectedItem();sframe.sendFD.setTe*t( ); 退出事件:添加退出功能,不然直接点叉叉退出,会报错。class E*itListener e*tends WindowAdapterClient client;public E*itListener(Client c)client=c; publicvoid windowClosing(WindowEvent e)client.close();System.e*it(0);2.Client类模块:关键模块,通过效劳器IP地址与端口建立连接,在控制台输入名字,发送给效劳器,效劳器会进展上线提醒与更新用户列表的操作。publicclass Client public ServiceFrame sf;private Socket csocket;private DataInputStream in;private DataOutputStream out;publicstaticvoid main(String args) BufferedReader in = new BufferedReader(new InputStreamReader(System.in); System.out.println(请输入一个名字: ); String who= ;try who=in.readLine().trim(); /控制台获得名字 catch(IOE*ception e) e.printStackTrace(); new Client(who,127.0.0.1,9992); 在Client的构造函数中实现对效劳器消息的解析,承受消息str11. 假设str1以$结尾,说明是有用户上线,在所有用户消息区域显示该消息,并且更新每一个用户的好友列表。2. 假设str1以结尾,说明这是一条私聊消息,解析其中的名字信息,假设该用户的名字在里面,才显示该消息。3. 假设str1以下线结尾,说明有用户下线,在所有用户消息区域显示该消息,并在所有用户的用户列表中删除该用户的信息最后,显示当前在线人数。public Client(String who,String server,int port) sf=new ServiceFrame(who+ 的客户端); String str1 = null;sf.but.addActionListener(new ActListener(this,sf);sf.addWindowListener(new E*itListener(this);trycsocket =new Socket(server,port);in=new DataInputStream(new BufferedInputStream(csocket.getInputStream();out=new DataOutputStream(new BufferedOutputStream(csocket.getOutputStream();out.writeUTF(who); out.flush(); /名字发给效劳器while(true)str1 = in.readUTF(); /重点!,效劳器端发来的消息if(str1.endsWith($) /假设以$结尾,则增添用户 int inde* = str1.lastInde*Of($); String str2 = str1.substring(0,inde*);sf.friendlist.addItem(str2.trim(); elseif(str1.endsWith() /以结尾为私聊信息 str1=str1.substring(0,str1.length()-1);if(str1.contains(who)sf.showAT.append(- +str1+n); elseif(str1.endsWith(下线) /用户下线,删除此用户 int inde* = str1.lastInde*Of(下线); String str2 = str1.substring(0,inde*);sf.friendlist.removeItem(str2.trim(); sf.showAT.append(- +str1+n); sf.showCount.setTe*t(在线人数:+(sf.friendlist.getItemCount()-1); /动态更新在线人数 catch(E*ception e) System.out.println(Server Error);this.close();System.e*it(0); 第四章 运行结果1.效劳器控制台显示并记录登录,退出信息。2.在客户端控制台输入名字进入聊天室。3.聊天界面显示客户端名字,好友列表,在线人数等信息。4.私聊,群聊显示,假设选择所有人则为群聊,选择*一个人,则为私聊。如下列图,群聊消息,在所有客户端都显示,私聊信息只会在发送者与承受者中显示。5.人数动态刷新。第五章 课程设计总结从收到题目的茫然无措,不知从何下手,到最后交出的成果,真的让我学到了很多,可能比一学期的JAVA和网络课程设计中学到的关于TCP协议的知识还要多,所以很感这次课程设计,有效果也很有意义,*种程度上比上课效果还好。说说完成课程设计的整个过程吧。刚看到可以选择的六个题目时,犹如晴天霹雳,别说用代码实现了,连题目要求都不理解,上课恍惚听教师提到过这个知识点,可是重要的容却一点也不知道,而且,由于要做图形界面,所以用JAVA会更简单点,但JAVA也忘得差不多了,所以只能从头来过,刚开场的3周,一点有关课程设计的代码都没写,拿着一本从零开场学JAVA把JAVA根底知识,尤其是关于网络编程,线程,图形界面的知识,狠狠地补了一把,终于更看懂一些程序构造清晰,没有反射,泛型等高端用法的程序了。在这过程中发现,做一个普通的网络聊天室,似乎不要用太多网络知识,懂得Socokt和TCP的使用即可,于是开场慢慢敲代码了。先把效劳器与客户端搭建起来,只能实现连接上的作用,但什么功能都没有,那时,以为能连接上了,那实现一些私聊,群聊的功能应该很简单,但现实确是,只能脑中想象,真的用代码实现,却总是错误百出,做的心灰意冷,尤其是私聊功能的实现,刚开场,想让效劳器直接向承受者与发送者发送消息,但总是不如人意,折腾了大概一星期,才意识到TCP协议就是用自己定义的一些规则,在效劳器与客户端之间传递消息,可以添加关键字,再解析。于是才解决私聊问题,然后添加好友列表与更新好友的功能也在跌跌撞撞中实现了。窗口的布局,刚开场想用网格包布局,但用的很不熟练,导致布局不理想,无奈,只能用最根本的布局了,所以界面看上去很普通。想发送图片,却发现文本区域根本不能显示图片,能用JEditorPane实现,但有BUG,不知如何调试,书上,网上也没找到能解决的方法,只能放弃了。 课程设计在这种不断学习与摸索中差不多完成了,说说这次课程设计的缺乏吧。1. 学过的知识不结实,所以花费了大量时间用来学习根底知识,那些应该在以前就掌握的。2. 程序界面很普通,像教师说的一样,是最最古老的聊天系统,没有什么花哨。3. 没能实现附加功能,像加密传输,文件传送等功能。其实,挺遗憾的,因为以前选修过密码学,应该能够实现简单的DES加密的。4. 没有用到JDBC,把用户信息存储到数据库表中,实行账号密码登录,提高系统的平安性。做了这么多的课程设计,最大的体会就是用心去做,用心去学,你一定能学到很多知识,而且这是对学过的知识的应用,所以比单一的上课更有意思。对于自己能独立的完成课程设计,还是颇为满意的,至少努力没有白费,学到的知识也非常多,最重要的应该是理解了TCP协议的原理,并学会了简单的应用,JAVA编程水平得到了一定的提高,面向对象的思想比以往更清晰了。第六章 附录6.1参考文献从零开场学JAVA 王发波 中国铁道Java 2实用教程 耿祥文 清华大学6.2源代码效劳器代码:package service;import java.io.*;import java.util.*;import .*;publicclass Server public Server(int port) throws IOE*ceptionServerSocket server=new ServerSocket(port);while(true)Socket conn=server.accept(); /建立客户端套接字DataInputStream in =new DataInputStream(conn.getInputStream();String who=in.readUTF();System.out.print(Client +(ip:+conn.getInetAddress()+)+who+ 进入!+n);ServerHander=new ServerHander(who,conn);.start();publicstaticvoid main(String args)throws IOE*ceptionnew Server(9992);class ServerHander e*tends ThreadSocket socket;DataInputStream in;DataOutputStream out;String who;protectedstatic Vectorclientlist=new Vector() ; /把用户线程放入可变对象数组public ServerHander(String name,Socket socket) throws IOE*ceptionthis.who = name;this.socket = socket;in =new DataInputStream(new BufferedInputStream(socket.getInputStream();out =new DataOutputStream(new BufferedOutputStream(socket.getOutputStream();publicvoid run()tryclientlist.addElement(this); /VECTOR中增加新线程sendallclient(who+ 上线);sendclientlist(); /为每一个客户端更新在线用户while(true) String msg=in.readUTF();int inde* = msg.lastInde*Of(); /对客户端发过来的信息做相应的处理 String str = msg.substring(inde*+1,msg.length(); /取得发送对象和发送的消息 msg=msg.substring(0,inde*);if(str.equals(所有人)=false) sendallclient(who+ 对+str+ 说: +msg+); /不是发给所有人则增添标记 elsesendallclient(who+ 对所有人 说: +msg); catch(IOE*ception e)System.out.println(error);finallyclientlist.removeElement(this);System.out.print(Client +(ip:+socket.getInetAddress()+)+who+ 退出!+n);sendallclient(who+ 下线);trysocket.close();catch(IOE*ception e*)System.out.println(clsing);/发送消息给所有用户protectedstaticvoid sendallclient(String msg) synchronized (clientlist)Enumeration allclients=clientlist.elements();while(allclients.hasMoreElements()ServerHander serh=(ServerHander)allclients.ne*tElement();tryserh.out.writeUTF(msg);serh.out.flush();catch(IOE*ception e*c)serh.interrupt();/更新用户列表publicstaticsynchronizedvoid sendclientlist()for(int j=0;jclientlist.size();j+)ServerHander allclients1=clientlist.elementAt(j);if(j=clientlist.size()-1) /假设是新增用户,把vector中的所有用户都发送过去for(int i = 0;iclientlist.size();i+) ServerHander allclients2=clientlist.elementAt(i);try allclients1.out.writeUTF(allclients2.who+$); allclients1.out.flush(); catch(IOE*ception e*c) allclients1.interrupt(); else /老用户,只增加新来的用户 ServerHander allclients3=clientlist.lastElement();try allclients1.out.writeUTF(allclients3.who+$); allclients1.out.flush(); catch(IOE*ception e*c) allclients1.interrupt(); 客户端代码:package service;import java.io.*;import .*;import java.awt.*;import java.awt.event.*;import java*.swing.*;publicclass Client public ServiceFrame sf;private Socket csocket;private DataInputStream in;private DataOutputStream out;publicstaticvoid main(String args) BufferedReader in = new BufferedReader(new InputStreamReader(System.in); System.out.println(请输入一个名字: ); String who= ;try who=in.readLine().trim(); /控制台获得名字 catch(IOE*ception e) e.printStackTrace(); new Client(who,127.0.0.1,9992); public Client(String who,String server,int port) sf=new ServiceFrame(who+ 的客户端); String str1 = null;sf.but.addActionListener(new ActListener(this,sf);sf.addWindowListener(new E*itListener(this);trycsocket =new Socket(server,port);in=new DataInputStream(new BufferedInputStream(csocket.getInputStream();out=new DataOutputStream(new BufferedOutputStream(csocket.getOutputStream();out.writeUTF(who); out.flush(); /名字发给效劳器while(true) str1 = in.readUTF(); /重点!,效劳器端发来的消息if(str1.endsWith($) /假设以$结尾,则增添用户 int inde* = str1.lastInde*Of($); String str2 = str1.substring(0,inde*);sf.friendlist.addItem(str2.trim(); elseif(str1.endsWith() /以结尾为私聊信息 str1=str1.substring(0,str1.length()-1);if(str1.contains(who)sf.showAT.append(- +str1+n); elseif(str1.endsWith(下线) /用户下线,删除此用户 int inde* = str1.lastInde*Of(下线); String str2 = str1.substring(0,inde*);sf.friendlist.removeItem(str2.trim(); sf.showAT.append(- +str1+n); sf.showCount.setTe*t(在线人数:+(sf.friendlist.getItemCount()-1); /动态更新在线人数 catch(E*ception e) System.out.println(Server Error);this.close(); System.e*it(0); protectedvoid send(String msg) /发送消息给效劳器的方法tryout.writeUTF(msg);out.flush(); catch(E*ception e) protectedvoid close()trysf.dispose();out.close();in.close();csocket.close(); catch(IOE*ception e*) classServiceFramee*tends Frame JTe*tArea showAT; JTe*tField sendFD; oBo* friendlist; utton but; JLabel showCount; JScrollPane te*tAreaScrollPane; JPanel te*tFieldPanel = new JPanel();public ServiceFrame (String winname)super(winname); /继承父类的名字setSize(500,400);te*tFieldPanel.setLayout(new FlowLayout(0,10,10);showAT = new JTe*tArea(400,400);showAT.setEditable(false);te*tAreaScrollPane = new JScrollPane(showAT);add(te*tAreaScrollPane, BorderLayout.CENTER);add(te*tFieldPanel, BorderLayout.SOUTH);friendlist = new oBo*();friendlist.addItem(所有人);te*tFieldPanel.add(friendlist);sendFD = new JTe*tField(20);te*tFieldPanel.add(sendFD);but = new utton(发送);but.setMnemonic(KeyEvent.VK_ENTER);te*tFieldPanel.add(but);showCount = new JLabel(在线人数:1);te*tFieldPanel.add(showCount);show();class ActListener implements ActionListener Client client; ServiceFrame sframe;public ActListener(Client c,ServiceFrame sf)client=c;sframe=sf; publicvoid actionPerformed(ActionEvent e) /发送信息,并以作为私聊标记client.send(sframe.sendFD.getTe*t().trim()+sframe.friendlist.getSelectedItem();sframe.sendFD.setTe*t( ); class E*itListener e*tends WindowAdapterClient client;public E*itListener(Client c)client=c; publicvoid windowClosing(WindowEvent e)client.close();System.e*it(0);. z.
展开阅读全文
相关资源
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!