您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 广告经营 > 类似QQ的P2P聊天系统
一、需求分析1.系统目的通过计算机网络的课程设计,使学生了解掌握TCP、UDP协议原理了解、掌握应用协议设计的思想。掌握开发建立和管理计算机网络的方法。能熟练地运用网络操作系统进行网络的建设和管理。培养学生自学能力和独立分析问题、解决问题的能力包括学会自己分析解决问题的方法,对设计中遇到的问题,能通过独立思考、查阅工具书、参考文献,寻找解决方案。利用Socket套接字进行网络通信。熟悉各种网络协议,实现基于服务器转发的任意多点间的数据共享和交换。体会开发、建立于管理计算机网络的全部过程。掌握基于服务器客户端机制的数据交换的实现思想及通信原理。掌握TCP/IP体系的结构及网络中的通信方式C/S、P2P方式。培养学生计算机网络的应用能力,初步掌握计算机网络分析与设计的基本方法。2.课程设计要求分组:最多4人/组内容:网络协议编程语言:C#题目:点对点数据交换(P2P):实现基于服务器转发的任意多点间的数据共享与交换。类似P2P的QQ聊天系统,有客户端和服务器端。服务器端记录当前在线客户列表,把客户列表发送给每一个在线客户,并实时刷新。任一个客户可以和任意其它的客户进行交互,即从在线客户列表中选择一个或一组其它客户通过服务器转发彼此进行交互,包括信息交互,文件交互。3.操作流程系统功能定义系统界面设计系统功能设计C/S服务器通信线路信息流处理调试程序,测试程序的健壮性4.开发工具与开发平台该软件在Windows7,VS2008平台下开发完成并通过调试。二、总体设计1.系统基本功能1、当用户登陆进入聊天室之后,其IP会在在线用户列表里显示2、通过选择用户后点击会话按钮弹出新窗口与其他在线用户进行即时通信。3、在聊天窗口时发送信息,点击发送按钮将信息发送出去。4、点击关闭按钮关闭当前装口,结束会话。2.系统架构图1系统架构图3.模块划分图2客户模块图3服务器模块4.各个模块之间关系各模块之间通过报文相互交互,均独立实现功能。但是在界面设计上有如上图关系用户列表、离线按钮、会话按钮在主界面上,其他各模块之间依赖事件响应机制互相调用。三、详细设计1.网络通信原理(1)面向连接的通信方式:在TCP/IP网络中两个进程间的相互作用的主机模式是客户机/服务器模式(Client/Servermodel)。该模式的建立基于以下两点:1、非对等作用;2、通信完全是异步的。(2)客户机/服务器模式在操作过程中采取的是主动请示方式,首先服务器方要先启动,并根据请示提供相应服务:(过程如下)服务器1、打开一通信端口并告知本地主机,它愿意在某一个公认地址上接收客户请求。2、等待客户请求到达该端口。3、接收到重复服务请求,处理该请求并发送应答信号。4、返回第二步,等待另一客户请求5、关闭服务器。客户方:1、打开一通信通道,并连接到服务器所在主机的特定端口。2、向服务器发送服务请求报文,等待并接收应答;继续提出请求……3、请求结束后关闭通信通道并终止。2、流程:(1)客户端:图4客户端流程图(2)服务器端:图5服务器端程序流程图(3)客户端与服务器端交互图6服务器客户交互图3、数据结构(1)通信节点Point客户名称:Account客户IP地址:IpAddress客户端口:Port(2)报文packet图7通信报文图8登陆报文图9离线报文图10消息报文图11更新在线客户列表报文报文类型type:报文类型type有:login(登陆)、off(离线)、update(更新在线客户列表)、msg(消息)报文源点:source(Point)报文源点结构:sourceAccount,sourceIPAddress,sourcePort报文目的节点:destinationList报文目的节点结构:destionationAccount,destinationIp,destinationPort;destionationAccount,destinationIp,destinationPort;…destionationAccount,destinationIp,destinationPort;报文内容:content报文格式:type#source#destinationList#content。即分为四段类型#源信息#目的信息#正文,每段之间用#号分隔。在目的信息这段中,若有多个目的地,则每个目的地信息之间用分号分隔,如:目的1信息;目的2信息;……目的N信息。每个目的信息以及源信息携带3个字段用户名、IP地址、端口他们用逗号分隔,如:用户名,IP地址,端口4、协议结构TCP协议:TCP协议的实现采用C#提供的Socket套接字其具体实现如下(1).创建套接字——socket()功能:使用前创建一个新的套接字格式:SOCKETPASCALFARsocket(intaf,inttype,intprocotol);参数:af:通信发生的区域type:要建立的套接字类型procotol:使用的特定协议(2).指定本地地址——bind()功能:将套接字地址与所创建的套接字号联系起来。格式:intPASCALFARbind(SOCKETs,conststructsockaddrFAR*name,intnamelen);参数:s:是由socket()调用返回的并且未作连接的套接字描述符(套接字号)。其它:没有错误,bind()返回0,否则SOCKET_ERROR地址结构说明:(3).建立套接字连接——connect()和accept()功能:共同完成连接工作格式:intPASCALFARconnect(SOCKETs);SOCKETPASCALFARaccept();4).监听连接——listen()功能:用于面向连接服务器,表明它愿意接收连接。格式:intPASCALFARlisten();5).数据传输——send()与Receive()功能:数据的发送与接收格式:intPASCALFARsend(Byte[]sendInfo);intPASCALFARReceive(Byte[]recInfo);由于需要实现服务器转发,所以客户端发送的消息必须先封装再发送。(4)C/S信息图12C/S信息交互图(5)通信过程程序设计图13C/S通信过程程序设计图四、系统实现1软件运行过程1)图14服务器主界面开启2)图15配置服务器3)图16配置完成启动服务器4)5)图17用户登陆界面图18配置客户端6)图19三个用户登陆后服务器列表更新7)图20用户1给用户3发送信息helloworld8)图21用户3接收到用户1消息9)图22用户1群发给用户2用户3消息thisismyprogram10)图23用户2接收到该群发消息11)图24用户3接收到该群发消息12)图25用户2离线后客户端用户列表更新13)图26用户2离线后服务器端用户列表更新14)图27服务器停止用户列表清空2、编码实现(部分)(1)节点类publicclassPoint{privatestringaccount;publicstringAccount{get{returnaccount;}set{account=value;}}privatestringipAddress;publicstringIpAddress{get{returnipAddress;}set{ipAddress=value;}}privatestringport;publicstringPort{get{returnport;}set{port=value;}}privateboolisSelected;publicboolIsSelected{get{returnisSelected;}set{isSelected=value;}}}(2)报文封装publicListPointResolveDestination(stringpacket){ListPointpointList=newListPoint();string[]msgArr=packet.Split('#');if(msgArr.Length==4){string[]destArr=msgArr[2].Split(newchar[]{';'},StringSplitOptions.RemoveEmptyEntries);foreach(stringdestindestArr){string[]destInfo=dest.Split(newchar[]{','},StringSplitOptions.RemoveEmptyEntries);if(destInfo.Length==3){PointdestPoint=newPoint();destPoint.Account=destInfo[0];destPoint.IpAddress=destInfo[1];destPoint.Port=destInfo[2];pointList.Add(destPoint);}}}returnpointList;}(3)服务器监听客户端请求publicvoidrecieveLogin(){Socketlistener=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);listener.Bind(newIPEndPoint(IPAddress.Any,int.Parse(serPort.Text)));listener.Listen(10);while(true){//服务器监听,如有客户登陆,向下执行Socketsocket=listener.Accept();byte[]messRec=newbyte[1024];intnumBytes=socket.Receive(messRec);socket.Shutdown(SocketShutdown.Both);socket.Close();if(numBytes0){stringreplyMes=Encoding.UTF8.GetString(messRec,0,numBytes);stringtype=ResolveType(replyMes);if(type==login){//添加该客户在线客户列表中后,向每一个在线的客户发送新的客户列表信息PointnewPoint=ResolveSource(replyMes);clientList.Add(newPoint);////加载客户列表BeginInvoke(newShowClientListDelegate(ShowClientList),newobject[]{clientList});stringmessage=string.Empty;foreach(PointcinclientList){message+=string.Format({0},{1},{2};,c.Account,c.IpAddress,c.Port);}stringpacket=PackageInfo(update,serPoint,null,message);foreach(PointpinclientList){Socketsender=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);IPEndPointdestPoint=newIPEndPoint(IPAddress.Parse(p.IpAddress),int.Parse(p.Port));sender.Connect(destPoint);byte[]cliBuffer=Encoding.UTF8.GetBytes(packet);sender.Send(cliBuffer);sender.Shutdown(SocketShutdown.Both);sender.Close();}}if(type==off){//将该客户从在线客户列表中删除后,向
本文标题:类似QQ的P2P聊天系统
链接地址:https://www.777doc.com/doc-5915786 .html