




已阅读5页,还剩14页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
网络编程课程设计报告题 目: 简单聊天室设计 院 系: 专业班级: 学 号: 学生姓名: 指导教师: 2016 年 1 月 6 日1.引言1) 本课题的来源随着网络普及和上网人数的大增,在国内各大门户网站都架设了大型聊天室。如:新浪聊天室、中华网社区聊天室、搜狐等都成为网民们的热门聊天室。以新浪聊天室为例看,聊天室呈现积聚人气作用,并开设不同主题的聊天室以使网民们具有针对性的使用聊天室。本人计划设计一个实现基于Java语言的聊天室的Windows网络编程,启动服务器后,客户端运行,向服务器端发出请求,连接成功后,会弹出一个聊天室的界面,该界面有私聊(可加入生动的表情描述)、群聊、发送文件等功能,客户可以根据自己的需要选择不同的功能。具体任务是实现文件的接收功能,启动服务器监听后,接收客户端发来请求,安排线程接收对方发来的文件(例如文档、照片、音乐、电影等)并存入指定的文件夹中。2)本系统涉及的知识点 1、套接字Socket的建立、连接、关闭,客户端和服务器端的输入/输出流的连接。 2、Java中的多线程及线程的常用方法、Runnable接口。 3、基于SWING的图形用户界面设计:布局设计、文本组件、按钮与标签组件、列表组件等。 4、InetAddress类。 5、输入/输出流:文件、文件字节流、文件字符流、缓冲流、数据流。 3)功能要求(1)在服务器端和客户端分别创建一个套接字对象,通过输入输出流连接在一起。套接字调用close()方法关闭双方的套接字连接。(2)使用多线程处理套接字连接,把服务器端或客户端读取的数据放在一个单独的线程中去进行,防止服务器端或客户端读取数据可能引起的堵塞。服务器端收到一个客户的套接字后,应该启动一个专门为该客户服务的线程。(3)成功连接后,在图形界面中用户可以根据自己的需要进行不同的操作,如:群聊天、和某一个用户单独聊天(可加入生动的表情描述)、发送文件等。在界面中会显示用户的聊天记录。4)开发环境的选择在进行开发之前,首先决定的第一个问题就是,该使用什么开发环境来编写该系统?以目前常用的开发语言来讲有C/C+、.NET技术,JAVA、 Visual Basic几种。还有Eclipse,、Borland JBuilder等,这些并不是程序语言,而是程序语言在建构程序时的“集成开发工具”,不过它们在开发设计的过程中也占有相当重要的角色,因为选用正确的集成开发工具,可以加速程序设计的进行、测试与排错,因而对整体进度具有决定性的影响。基于以下几点,选择JAVA语言开发技术。1、就执行平台而言,必须考虑的问题之一是用户可能使用的操作系统。用户可能使用的是Windows Linux。JAVA语言具有平台无关性,可以不需要任何修改就可以运行在支持JAVA的任何计算机上。2、JAVA的Swing 组件开发技术可以开发丰富的图形界面,并且Swing API类提供了丰富的外部接口和方法,可以方便实现系统功能。3、就项目开发而言,纯粹的面向对象,加上数量巨大的类所提供的方法(函数)库的支持,使得利用Java开发各种应用程序,可以说是易如反掌。此外,在程序除错、修改、升级和增加新功能等方面,因其面向对象的特性,使得这些维护也变得非常容易。4、Java支持内在的多线程运行,提供分布式的并发机制,运行效率高。5、异常处理,为了使Java程式更稳定、更安全,Java引入了异常处理机制。能够在程序中产生异常情况的地方,执行相对应的处理,不至于因突发或意外的错误造成执行中断或是死机。通过这种异常处理,不仅能够清晰地掌握整个程序执行的流程,也使得程序的设计更为严谨。6、高性能,Java可以在运行时直接将目标代码翻译成机器指令。Sun用直接解释器一秒钟内可调用300,000个过程。翻译目标代码的速度与C/C+的性能没什么区别。7、网络功能,Java可以说是借助因特网而重获新生的,自然具备编写网络功能的程序。不论是一般因特网局域网的程序,如Socket、Email、基于Web服务器的Servlet、JSP程序,甚至连分布式网络程序,如CORBA、RMI等的支持也是非常丰富的,使用起来也很方便。5)开发技术的选择 本课题选择了java Socket技术开发网络聊天室。什么是socket? socket是一种用于表达两台机器之间连接“终端”的软件抽象。对于一个给定的连接,在每台机器上都有一个socket,你可以想象一个虚拟的管道工作在两台机器之间,“管道”连在两台机器的socket上。当然,物理硬件和两台机器之间的“管道”这些连接装置都是未知的,抽象的所有目的就是为了让我们不必了解更多的细节。 简单的说,一台计算机上的socket同另一台计算机通话创建一个通信信道,程序员可以用这个信道在两台机器之间发送数据。当你发送数据时,TCP/IP协议栈的每一层都给你的数据里添加适当的报头。有个好消息是java语言隐藏了所有这些细节,这也是为什么他们有时被叫做“流socket”。 思考一下socket像电话听筒一样在电话的任意一端你和我通过一个专门的信道来进行通话和接听。会话将一直进行下去直到我们决定挂断电话(除非我们使用蜂窝电话),除非我们挂断电话,否则我们各自的电话线路都会占线。 如果你需要在两台机器之间进行通讯而不使用高级机制像ORBs(以及CORBA, RMI, IIOP等等),socket比较适合你。Socket的底层机制则相当棘手。幸运的是,java平台给我们一些虽然简单但是相当强大的高层抽象以至于我们创建和使用socket更加容易一些。一般而言,java socket有下面两种类型:TCP socket(由Socket类实现,下面的章节我们将对其讨论)UDP socket(由DatagramSocket类实现)TCP和UDP扮演同样的角色,但是实现是不同的。两者都接收传输协议数据包并把它们传递到表示层。TCP把信息分解成数据包(datagrams)并在接收端重新组装起来。它还对丢失的数据包进行重新传输的请求。TCP减少了上层的担忧。UDP没有组装和重传请求的功能。它只是传输数据包。更高层的层必须确保信息的完整性以及组合顺序的正确性。2.功能设计1、Socket socket = new Socket(String host,int port);客户端创建Socket对象,host是服务器端的IP地址,port是一个端口号,该对象用于连接服务器。2、BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream();创建一个使用默认大小输入缓冲区的缓冲字符输入流。该输入流的指向是一个Reader流,Reader流将数据读入缓冲区,BufferedReader再从缓冲区中读取数据。InputStreamReader是字节流通向字符流的桥梁:它使用指定的charset读取字节并将其解码为字符。getInputStream()获取字节输入流。3、PrintStream ps = new PrintStream(socket.getOutputStream();创建新的打印流,PrintStream 为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。它还提供其他两项功能。与其他输出流不同,PrintStream 永远不会抛出 IOException;而是,异常情况仅设置可通过 checkError 方法测试的内部标志。4、File file = getFile();调用getFile()函数返回一个file的的路径,提示用户输入一个路径,判断是否存在该文件, 如果输入非法给予提示, 重新输入。5、ps.println(file.getName(); ps.println(file.length();将文件名和大小发送到服务端。6、String msg = br.readLine();if(已存在.equals(msg) 接收服务器发送回来的是否存在的结果. 如果文件已存在, 打印提示, 客户端退出. 如果不存在, 准备开始上传。7、long finishLen = Long.parseLong(msg); 服务器端文件的长度。8、FileInputStream fis = new FileInputStream(file); 创建FileInputStream从文件中读取数据,OutputStream out = socket.getOutputStream();输出字节流,输出流接收输出字节并将这些字节写出到Socket的输出流。9、fis.skip(finishLen); 从输入流中跳过并丢弃finishLen个字节的数据,即跳过服务端已完成的大小。10、len = fis.read(byte buffer);从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。11、out.write(byteb,intoff,intlen) 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。3.聊天室界面4.全部程序:服务器端:package chat;import .*;import java.io.*;import java.util.*;public class ChatServerpublic static void main(String args)throws ExceptionServerSocket svSocket =null;Vector threads = new Vector();try svSocket = new ServerSocket(5555);System.out.println (listening.);catch (Exception ex) System.out.println (Server create ServerSocket failed!);return;tryint nid = 0;while(true)Socket socket = svSocket.accept();System.out.println (accept a client);ServerThread st = new ServerThread(socket,threads);st.setID(nid+);threads.add(st);new Thread(st).start();for(int i=0;i threads.size();i+)ServerThread temp = (ServerThread)threads.elementAt(i);System.out.println (Listen again.);catch(Exception ex)System.out.println (server is down);class ServerThread implements Runnableprivate Vector threads;private Socket socket = null;private DataInputStream in = null;private DataOutputStream out = null;private int nid;public ServerThread(Socket socket,Vector threads)this.socket = socket;this.threads = threads;try in = new DataInputStream(socket.getInputStream();out = new DataOutputStream(socket.getOutputStream();catch (Exception ex) public void run()System.out.println (Thread is running);trywhile(true)String receive = in.readUTF();if(receive = null) return;/下线通知if(receive.contains(黯然下线了)for(int i=0;i threads.size();i+)ServerThread st = (ServerThread)threads.elementAt(i);st.write(*+receive+*);/上线通知else if(receive.contains(上线了)for(int i=0;i threads.size();i+)ServerThread st = (ServerThread)threads.elementAt(i);st.write(: +receive);/作为服务器监听中else if(receive.contains(监听中)for(int i=0;i threads.size();i+)ServerThread st = (ServerThread)threads.elementAt(i);st.write(*+receive+* );/发送消息else if(receive.contains(说)/发送广播消息if(receive.contains(大家)for(int i=0;i threads.size();i+)ServerThread st = (ServerThread)threads.elementAt(i);st.write(: +receive);/发送指定消息elseint temp=receive.indexOf(); /获得接收者ID号String tempS=receive.substring(temp+1,temp1); int i=Integer.parseInt(tempS);/指定接收者输出ServerThread st = (ServerThread)threads.elementAt(i);st.write(: +receive);/发送者自己也输出st = (ServerThread)threads.elementAt(getID();st.write(: +receive);elseServerThread st = (ServerThread)threads.elementAt(getID();st.write(*+receive+*);catch(Exception ex)threads.removeElement(this); ex.printStackTrace();trysocket.close();catch(Exception ex)ex.printStackTrace();public void write(String msg)synchronized(out)tryout.writeUTF(msg);catch(Exception ex)public int getID()return this.nid;public void setID(int nid)this.nid = nid;服务器端的文件传送:package chat;import java.io.BufferedReader;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintStream;import .ServerSocket;import .Socket;import java.text.SimpleDateFormat;import java.util.Date;import javax.swing.JOptionPane;public class filesendServerpublic void filereceive() throws Exception /1.创建ServerSocket, 在循环中接收客户端请求, 每接收到一个请求就开启新线程处理 ServerSocket serverSocket = new ServerSocket(1234); JOptionPane.showMessageDialog(null,服务已启动,绑定1234端口!); while(true) Socket socket = serverSocket.accept(); new fileServerThread(socket).start(); class fileServerThread extends ThreadSocket socket;public fileServerThread(Socket socket) this.socket = socket;public void run() FileOutputStream fos = null;try /3.获取输入输出流BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream();PrintStream ps = new PrintStream(socket.getOutputStream();/7.接收文件, 查找是否存在. 如果存在, 给写一个消息给客户端, 服务端线程结束. 如果不存在, 写消息给客户端, 准备开始上传.String fileName = br.readLine(); long fileLen = Long.parseLong(br.readLine();File dir = new File(upload);dir.mkdir();File file = new File(dir,fileName);if(file.exists() & file.length() = fileLen) / 文件已存在, length()即为文件大小, 文件不存在length()为0ps.println(已存在);return;elseps.println(file.length(); / 文件已存在, length()即为文件大小, 文件不存在length()为0/10.从Socket的输入流中读取数据, 创建FileOutputStream写出到文件中String time = new SimpleDateFormat(yyyy-MM-dd HH:mm:ss).format(new Date();System.out.println(time + + (file.exists() ? 开始断点续传: : 开始上传文件: ) + file.getName();long start = System.currentTimeMillis();InputStream in = socket.getInputStream();fos = new FileOutputStream(file, true); / 文件存在就追加, 文件不存在则创建byte buffer = new byte1024;int len;while(len = in.read(buffer) != -1) /这个地方会堵塞,如果客服端没有关闭socket.服务器端读不到流末尾(-1)fos.write(buffer, 0, len);if(file.length() = fileLen) / 文件大小等于客户端文件大小时, 代表上传完毕break;fos.close();long end = System.currentTimeMillis();time = new SimpleDateFormat(yyyy-MM-dd HH:mm:ss).format(new Date();System.out.println(time + + 上传文件结束: + file.getName() + , 耗时: + (end - start) + 毫秒);ps.println(上传成功);socket.close(); catch (IOException e) if(fos != null)try fos.close(); catch (IOException e1) e1.printStackTrace();客户端的界面设计:package chat;import java.awt.*;import java.io.*;import .*;import java.awt.event.*;import javax.swing.*;public class Client public static void main(String args) new ChatClient(); class ChatClient extends Frame implements ActionListener, Runnableprivate static final long serialVersionUID = -4149839042245330513L;public Button listen,connection,sendtoall,sendtoone,exit,filesend;public JComboBox emote;public TextField inputName,inputContent;public TextArea chatResult;public Socket socket=null;public DataInputStream in=null;public DataOutputStream out=null;public Thread thread;ChatClient()socket=new Socket();Box box1=Box.createHorizontalBox();listen=new Button(作为服务器监听);connection=new Button(连接服务器);filesend=new Button(发送文件);exit=new Button(退出);sendtoall=new Button(群聊);sendtoone=new Button(私聊);listen.setEnabled(false);filesend.setEnabled(false);sendtoall.setEnabled(false);sendtoone.setEnabled(false);inputName=new TextField(6);inputName.setBackground(new Color(162,231,250);inputContent=new TextField(22);inputContent.setBackground(new Color(162,231,250);chatResult= new TextArea(, 17,20,TextArea.SCROLLBARS_VERTICAL_ONLY);chatResult.setBackground(new Color(162,231,250);JLabel jlname=new JLabel(输入昵称);box1.add(jlname);box1.add(inputName);box1.add(listen);box1.add(connection);box1.add(filesend);box1.add(exit);Box box2=Box.createHorizontalBox();emote = new JComboBox();emote.setModel(new DefaultComboBoxModel(new String 表情, 微笑,甜笑, 惊喜, 嘻嘻, 扮酷, 嘿嘿, 傻笑, 好奇, 媚眼, 鬼脸, 陶醉,害羞, 生气, 嚷嚷, 发怒, 伤心, 高明, 菜鸟, 问号, 狂笑, 大哭,示爱, 呻吟, 想想 );emote.setEnabled(false);JLabel jlintput = new JLabel(输入聊天内容);box2.add(jlintput);box2.add(inputContent);box2.add(emote);box2.add(sendtoall);box2.add(sendtoone);listen.addActionListener(this);connection.addActionListener(this); filesend.addActionListener(this);exit.addActionListener(this);sendtoall.addActionListener(this);sendtoone.addActionListener(this);Box box3=Box.createHorizontalBox();box3.add(chatResult);thread=new Thread(this);Box box0=Box.createVerticalBox();box0.add(Box.createVerticalStrut(10);box0.add(box1);box0.add(Box.createVerticalStrut(10);box0.add(box3);box0.add(Box.createVerticalStrut(10);box0.add(box2);box0.add(Box.createVerticalStrut(10);add(box0);setBounds(10,30,500,400);setBackground(new Color(80,212,248);setVisible(true);validate();addWindowListener(new WindowAdapter()public void windowClosing(WindowEvent e)System.exit(0);try socket.close(); catch (IOException e1) e1.printStackTrace(); );public void actionPerformed(ActionEvent e) ActionProcess actionProcess=new ActionProcess(this);try actionProcess.action(e); catch (Exception e1) e1.printStackTrace();public void run()String s=null;while(true)trys=in.readUTF();chatResult.append(n+s);catch(IOException e)chatResult.setText(与服务器断开连接);trysocket.close();catch(Exception ep)break;客户端的界面事件处理:package chat;import java.awt.event.ActionEvent;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import .*;import javax.swing.JOptionPane;public class ActionProcess implements Runnable private ChatClient client;String name=;String sendtoname=; String sendtoID; String filename=;String filepath=;public ActionProcess(ChatClient client) this.client=client;public void action(ActionEvent e)throws Exceptionif(e.getSource()=client.connection)tryif(client.socket.isConnected()elseString addr=JOptionPane.showInputDialog(请输入服务器IP:);InetAddress address=InetAddress.getByName(addr);InetSocketAddress socketAddress=new InetSocketAddress(address,5555);client.socket.connect(socketAddress);client.in=new DataInputStream(client.socket.getInputStream();client.out=new DataOutputStream(client.socket.getOutputStream();name=client.inputName.getText();client.out.writeUTF(姓名为+name+的朋友风尘仆仆地上线了.);client.listen.setEnabled(true);client.filesend.setEnabled(true);client.sendtoall.setEnabled(true);client.sendtoone.setEnabled(true);client.emote.setEnabled(true);if(!(client.thread.isAlive()client.thread=new Thread(this);client.thread.start(); catch(IOException ee)if(e.getSource()=client.listen)tryname=client.inputName.getText();client.out.writeUTF(姓名为+name+的朋友正在监听中.);filesendServer filesendserver=new filesendServer();filesendserver.filereceive(); catch (Exception ee) ee.printStackTrace();if(e.getSource()=client.filesend)if(client.socket.isConnected()try filesendClient filesendclient=new filesendClient();filesendclient.filesend();client.out.writeUTF(成功发送文件!);catch (Exception ee) if(e.getSource()=client.exit) if(client.socket.isConnected()try name=client.inputName.getText();client.out.writeUTF(姓名为+name+的朋友黯然下线了.);client.out.flush(); client.out.close();client.socket.close(); catch (IOException e1) e1.printStackTrace();System.exit(0);String em=client.emote.getSelectedItem().toString();if (em.equals(表情) em = ; else em += 着;if(e.getSource()=client.sendtoall)if(client.socket.isConnected()name=client.inputName.getText();String s=client.inputContent.getText();if(s!=null)tryclient.out.writeUTF(name+em+对大家说:+s);client.out.flush(); client.inputContent.setText();catch(IOException e1)if(e.getSource()=client.sendtoone) if(client.socket.isConnected()sendtoID=JOptionPane.showInputDialog(请输入对方ID:);sendtoname=JOptionPane.showInputDialog(请输入对方姓名:);String s=client.inputContent.getText();name=client.inputName.getText();if(s!=null)tryclient.out.writeUTF(name+悄悄地+em+对+sendtoname+说:+s);client.out.flush(); client.inputContent.setText();catch(IOException e1) public void run()String s=null;while(true)trys=client.in.readUTF();client.chatResult.append(n+s);catch(IOException e)client.chatResult.setText(与服务器断开连接);tryclient.socket.close();catch(Exception ep)break;客户端的文件接收:package chat;import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.PrintStream;import .Socket;import javax.swing.JOptionPane;public class filesendClient public void filesend() throws Exception/1.创建Socket, 指定服务端IP地址和端口号, 连接服务器String sendtoIP=JOptionPane.showInputDialog(请输入对方IP:);Socket socket = new Socket(sendtoIP, 1234);/2.获取输入输出流BufferedReader br = new BufferedReader(new In
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 传染病竞赛试题及答案
- 安徽十校联考试卷及答案
- ICU(重症监护室)考试试题及答案
- 2025年自然灾害与应急管理考试试题及答案
- 2025年乌海学法减分题库及答案
- 山东级安全员证考试试题及答案
- 2025年护理学专业职称考试试卷及答案
- 幻想城堡的一天写童话作文5篇
- 新能源行业并购重组中知识产权评估技术创新模式探析(2025年)
- 2025年医疗器械GCP考试试题和答案
- GB/T 46150.1-2025锅炉和压力容器第1部分:性能要求
- 食品肉类供货合同范本
- 房屋土地兄弟分家协议书
- 四人合伙股份合同协议书
- 2025北京京剧院招聘工作人员10人备考试题及答案解析
- 中医药现代化国际市场拓展:2025年中医药国际市场竞争力提升策略报告
- OTC药品终端销售方案
- 医院宣传稿件写作方法
- 中药外敷的课件
- ECMO联合CRRT护理查房
- 医院安全生产检查台账
评论
0/150
提交评论