聊天系统实验报告

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

实验报告学部:理工学部课程名称:软件工程工具实验项目:聊天系统专业班级:姓名:学号:实验地点:B3-403指导教师:杨柳成绩:河北大学工商学院1实验目的(1)解决工作和生活中的信息交流不便的弊端。(2)掌握基于Socket的聊天程序的设计方法。(3)使用C/S构架,对网络编程有一定的了解。2实验要求(1)使用Socket异步套接字进行通信,实现点对点发送消息的功能。3实验内容3.1系统概述为了解决工作和生活中信息交流不变的弊端,设计和实现一个基于C/S结构的聊天系统。本系统使用Socket异步套接字进行通信,实现点对点发送消息的功能。该系统包括服务器端和客户端,服务器端的主要功能是使用Socket监听本机的端口,如果有连接请求则创建Socket连接,而客户端在使用时需要对服务器的端口发出请求,如果服务器存在,则建立连接,实现服务器端和客服端之间的通信。3.2系统分析与设计(1)使用前首先建立Socket连接。(2)服务器端与客户端之间的信息发送是该系统最基本的功能。(3)在C/S模式中,服务器与客户端是相互依赖的。(4)服务器端与客户端的聊天信息在界面的显示应按照用户的要求进行格式处理,这样更易于用户查看。3.3系统实现与测试系统用例图:系统时序图:请求连接连接响应发送消息监听端口请求连接发送消息接收消息服务器端客户端发送消息结束消息Server.java①单击启动按钮事件若服务器已启动则提示错误。若正常,启动服务器。publicvoidserverStart(intmax,intport)throwsjava.net.BindException;当端口号被占用则提示错误信息,若没有错误,则进行以下代码,启动服务器。clients=newArrayListClientThread();serverSocket=newServerSocket(port);serverThread=newServerThread(serverSocket,max);serverThread.start();isStart=true;②单击停止按钮停止服务器,若服务器未曾启动或停止失败则报错关闭服务器的方法publicvoidcloseServer()停止服务器线程,并给所有在线用户发送关闭命令,释放资源,停止此条为客户端服务的线程,关闭服务器端连接清空用户列表③群发服务器消息publicvoidsendServerMessage(Stringmessage){for(inti=clients.size()-1;i=0;i--){clients.get(i).getWriter().println(服务器:+message+(多人发送));clients.get(i).getWriter().flush();}}④服务器线程classServerThreadextendsThread{}内含构造方法和run方法publicvoidrun(){while(true){//try{Socketsocket=serverSocket.accept();服务器不停的等待客户端的链接。如果已达人数上限,提示“服务器在线人数已达上限,请稍后尝试连接”,并释放资源若符合要求,则开启对此客户端服务的线程ClientThreadclient=newClientThread(socket);client.start();clients.add(client);listModel.addElement(client.getUser().getName());contentArea.append(client.getUser().getName()+client.getUser().getIp()+上线!\r\n);为一个客户端服务的线程classClientThreadextendsThread{客户端线程的构造方法接收客户端的基本用户信息,反馈连接成功信息,反馈当前在线用户信息向所有在线用户发送该用户上线命令run方法不断接收客户端的消息,进行处理。下线命令断开连接释放资源,向所有在线用户发送该用户的下线命令更新在线列表,删除此条客户端服务线程⑤执行消息发送函数send()publicvoidsend();服务器还未启动或没有用户在线时,不能发送消息,提示错误。消息不为空时将消息群发。⑥转发消息dispatcherMessage()publicvoiddispatcherMessage(Stringmessage){StringTokenizerstringTokenizer=newStringTokenizer(message,@);Stringsource=stringTokenizer.nextToken();Stringowner=stringTokenizer.nextToken();Stringcontent=stringTokenizer.nextToken();message=source+说:+content;contentArea.append(message+\r\n);if(owner.equals(ALL)){//群发for(inti=clients.size()-1;i=0;i--){clients.get(i).getWriter().println(message+(多人发送));clients.get(i).getWriter().flush();}}}}}Client.java1.Send()函数如果没有连接服务器时,不能发送消息,弹出提示;若服务器已连接,则判断消息是否为空,消息为空则提示错误信息,不为空时调用sendMessage()函数将消息发出,textField清空。publicvoidsend(){if(!isConnected){JOptionPane.showMessageDialog(frame,还没有连接服务器,无法发送消息!,错误,JOptionPane.ERROR_MESSAGE);return;}Stringmessage=textField.getText().trim();if(message==null||message.equals()){JOptionPane.showMessageDialog(frame,消息不能为空!,错误,JOptionPane.ERROR_MESSAGE);return;}sendMessage(frame.getTitle()+@+ALL+@+message);textField.setText(null);}2.单击连接按钮时事件单击连接按钮时,如果处于连接上状态,则提示不能重复链接。if(isConnected){JOptionPane.showMessageDialog(frame,已处于连接上状态,不要重复连接!,错误,JOptionPane.ERROR_MESSAGE);return;}判断端口、IP地址、姓名是否为空,如果为空,抛出异常,提示错误信息,否则提示连接成功。3.单击断开按钮时事件单击断开按钮时,如果处于断开上状态,则提示不能重复断开抛出异常,通过设置flag调用closeConnection()调用判断服务器是否成功断开。btn_stop.addActionListener(newActionListener(){publicvoidactionPerformed(ActionEvente){if(!isConnected){JOptionPane.showMessageDialog(frame,已处于断开状态,不要重复断开!,错误,JOptionPane.ERROR_MESSAGE);return;}try{booleanflag=closeConnection();//断开连接if(flag==false){thrownewException(断开连接发生异常!);}JOptionPane.showMessageDialog(frame,成功断开!);}catch(Exceptionexc){JOptionPane.showMessageDialog(frame,exc.getMessage(),错误,JOptionPane.ERROR_MESSAGE);}}});4.单击发送按钮事件直接调用send()函数,完成发送。btn_send.addActionListener(newActionListener(){publicvoidactionPerformed(ActionEvente){send();}});5.连接服务器函数connectServer()socket描述IP地址和端口,根据端口号和服务器ip建立连接,是一个通信链的句柄。getInputStream方法获得网络连接输入,同时返回一个InputStream对象实例,赋值给writer,getOutputStream方法连接的另一端将得到输入,同时返回一个OutputStream对象实例,赋给reader。socket=newSocket(hostIp,port);//writer=newPrintWriter(socket.getOutputStream());reader=newBufferedReader(newInputStreamReader(socket.getInputStream()));接着通过sendMessage()函数发送客户端用户基本信息(用户名和ip地址),开启接收消息的线程,调用start()函数,如果连接成功,返回TRUE,messageThread=newMessageThread(reader,textArea);messageThread.start();isConnected=true;//已经连接上了returntrue;否则补货,返回FALSE。catch(Exceptione){textArea.append(与端口号为:+port+IP地址为:+hostIp+的服务器连接失败!+\r\n);isConnected=false;//未连接returnfalse;}6.closeConnection()函数synchronized保证在同一时刻最多只有一个线程执行该段代码。先发送断开连接命令给服务器,调用stop()停止接受消息线程,最后释放资源。publicsynchronizedbooleancloseConnection(){try{sendMessage(CLOSE);messageThread.stop();if(reader!=null){reader.close();}if(writer!=null){writer.close();}if(socket!=null){socket.close();}isConnected=false;returntrue;}catch(IOExceptione1){e1.printStackTrace();isConnected=true;returnfalse;}}User.java该类中包含两个成员变量,name和IP,用来定义用户对象。运行结果4、总结Socket是建立网络连接时使用的。在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别。不管是Socket还是ServerSocket它们的工作都是通过SocketImpl类及其子类完成的。通过使用socket以及线程完成基本的用户-服务器聊天,实现基本功能。

1 / 15
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功