北京邮电大学信息与通信工程学院第1页程序设计实践设计报告课题名称:聊天程序学生姓名:班级:班内序号:学号:日期:2014/6/6北京邮电大学信息与通信工程学院第2页1.课题概述1.1课题目标和主要内容聊天程序虽然形态各异,但就其本质,却是相同的。这种程序一般由两大部分组成:服务器端聊天程序和客户端聊天程序。服务器端聊天程序负责接收来自客户端的聊天信息,并且根据客户端的要求把这些信息转发到另外一个活多个客户中。客户端聊天程序则负责建立与维护与服务器端的连接,向服务器发送本客户的聊天内容,同时从服务器接收对方的响应。1.2系统的主要功能(1)可以手动输入服务器IP地址和端口号进行连接(客户端功能)。(2)可以手动建立服务器接受其他客户端的连接要求(服务端功能)。(3)可以发送消息给服务端,显示服务端传来消息(客户端功能)。(4)可以接收客户端发送的消息,并将消息传给所有在线的客户端(服务端功能)。2.系统设计2.1系统总体框架2.2系统详细设计服务端:[1]模块划分图及描述(1)在特定的端口上等待来自聊天客户的连接请求,并且需要维护一个客户连接表,以记录所有成功的连接。客户端通信底层TCP/IPCClientSocet服务器网卡CServerSocetTCP/IP通信底层网卡北京邮电大学信息与通信工程学院第3页(2)及时接收各个聊天客户发送过来的信息,然后把这些信息转发到一个或多个客户连接。(3)监控这些连接的状态,在客户主动离开或发生故障时从列表中删除相应的表项,并及时更新连接表。[2]类关系图及描述CServerSocket类的主要功能是实现OnAccept()消息,负责监听服务端口,是一个服务Socket。此类头文件代码如下://CServerSocketcommandtargetclassCChatDlg;classCServerSocket:publicCSocket{//Attributespublic:CChatDlg*m_dlg;UINTm_uPort;BOOLInit(UINTport,CChatDlg*dlg);//Operationspublic:CServerSocket(){};virtual~CServerSocket(){};//Overridespublic://ClassWizardgeneratedvirtualfunctionoverrides//{{AFX_VIRTUAL(CServerSocket)//使用类向导添加的public:virtualvoidOnAccept(intnErrorCode);//}}AFX_VIRTUAL//Generatedmessagemapfunctions//{{AFX_MSG(CServerSocket)//NOTE-theClassWizardwilladdandremovememberfunctionshere.//}}AFX_MSG//Implementationprotected:};/////////////////////////////////////////////////////////////////////////////北京邮电大学信息与通信工程学院第4页//{{AFX_INSERT_LOCATION}}//MicrosoftVisualC++willinsertadditionaldeclarationsimmediatelybeforethepreviousline.#endif//!defined(AFX_SERVERSOCKET_H__03952A19_3B2C_45BD_B9BB_FBBD072ED603__INCLUDED_)[3]存储结构、内存分配此模块用到了列表的存储结构客户端:[1]模块划分图及描述(1)建立和维护与服务器的连接,并且随时监测连接的状态。(2)把用户输入的信息及时发送到服务端,同时,随时准备好接收服务端的信息,并将它显示出来。(3)在用户退出聊天过程时要关闭与服务端的连接。[2]类关系图及描述CClientSocket类通过相应的OnReceive消息来接受数据,响应OnClose消息来断开对话的处理。CClientSocket类实现了以CArchive对数据进行的串行化。本类的头文件源代码如下:#includePackMessg.h///////////////////////////////////////////////////////////////////////////////CClientSocketcommandtargetclassCChatDlg;classCClientSocket:publicCSocket{//Attributespublic:CArchive*m_aSessionIn;CArchive*m_aSessionOut;CSocketFile*m_sfSocketFile;CChatDlg*m_dlg;boolm_bInit;//作为套接字是否被初始化的标记北京邮电大学信息与通信工程学院第5页boolm_bClose;//作为套接字是否被关闭的标记//Operationspublic:voidInit(CChatDlg*dlg);BOOLSendMessage(CPackMessg*msg);voidCloseSocket();public:staticintGetLocalHostName(CString&sHostName);//获得本地计算机名称staticintGetIpAddress(constCString&sHostName,CString&sIpAddress);//获得本地IPstaticintGetIpAddress(constCString&sHostName,BYTE&f0,BYTE&f1,BYTE&f2,BYTE&f3);//获得本地IPstaticCStringErrorReason(inttag);public:CClientSocket();virtual~CClientSocket();//Overridespublic://ClassWizardgeneratedvirtualfunctionoverrides//{{AFX_VIRTUAL(CClientSocket)//通过classwizard添加到类中的成员函数public:virtualvoidOnReceive(intnErrorCode);virtualvoidOnClose(intnErrorCode);//}}AFX_VIRTUAL//Generatedmessagemapfunctions//{{AFX_MSG(CClientSocket)//NOTE-theClassWizardwilladdandremovememberfunctionshere.//}}AFX_MSG//Implementationprotected:};///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}//MicrosoftVisualC++willinsertadditionaldeclarationsimmediatelybeforethe北京邮电大学信息与通信工程学院第6页previousline.#endif//!defined(AFX_CLIENTSOCKET_H__9A3B7A03_0D59_4A60_ABA2_35D6CA850937__INCLUDED_)总程序流程图:注销服务端?结束是将响应发送到各客户端开始建立服务端还是客户端初始化服务端初始化客户端服务端客户端连接服务端是否连接成功将客户端加入表尾准备发送消息检查连接将客户端从列表删除发送消息将响应发送到各客户端是否断开连接否北京邮电大学信息与通信工程学院第7页2.3关键算法分析算法1:CServerSocket::Init[1]算法功能初始化服务端[2]算法基本思想服务端建立套接字,并且进入监听状态。[3]算法空间、时间复杂度分析O(1)[4]代码逻辑(可用伪代码描述)BOOLCServerSocket::Init(UINTport,CChatDlg*dlg){m_uPort=port;m_dlg=dlg;if(Create(m_uPort)==FALSE){AfxMessageBox(服务器套接字创建失败!);returnFALSE;}if(this-Listen()==FALSE){AfxMessageBox(服务器监听错误!);returnFALSE;}m_dlg-SetDlgItemText(IDC_SHOWMESSAGE,服务器创建成功!);returnTRUE;}算法2:CClientSocket::OnReceive[1]算法功能接收数据[2]算法基本思想如果为客户端,将此响应传递到所有与此连接的客户端,如果为客户端,接收响应。[3]算法空间、时间复杂度分析O(n)、O(1)北京邮电大学信息与通信工程学院第8页[4]代码逻辑(可用伪代码描述)voidCClientSocket::OnReceive(intnErrorCode){//TODO:Addyourspecializedcodehereand/orcallthebaseclassCSocket::OnReceive(nErrorCode);do{CPackMessgtemp;temp.Serialize(*m_aSessionIn);m_dlg-m_sMsgList+=temp.m_strText+\r\n;m_dlg-SetDlgItemText(IDC_SHOWMESSAGE,m_dlg-m_sMsgList);intlinenum=((CEdit*)(m_dlg-GetDlgItem(IDC_SHOWMESSAGE)))-GetLineCount();((CEdit*)(m_dlg-GetDlgItem(IDC_SHOWMESSAGE)))-LineScroll(linenum);if(!m_dlg-m_bClient){for(POSITIONpos=m_dlg-m_connectionList.GetHeadPosition();pos!=NULL;){CClientSocket*t=(CClientSocket*)m_dlg-m_connectionList.GetNext(pos);if(t-m_hSocket!=this-m_hSocket){t-SendMessage(&temp);}}}}while(!m_aSessionIn-IsBufferEmpty());}算法3:CClientSocket::SendMessage[1]算法功能发送消息[2]算法基本思想检查连接情况,若断开,关闭对话,若连接,发送消息。[3]算法空间、时间复杂度分析O(1)北京邮电大学信息与通信工程学院第9页[4]代码逻辑(可用伪代码描述)BOOLCClientSocket::SendMessage(CPackMessg*msg){if(m_aSessionOut!=NULL){msg-Serialize(*m_aSessionOut);m_aSessionOut-Flush();returnTRUE;}else{//对方关闭了连接m_bClose=true;CloseSocket();m_dlg-CloseSessionSocket();returnFALSE;}}3.程序运行结果分析北京邮电大学信息与通信工程学院第10页北京邮电大学信息与通信工程学院第11页4.总结4.1课题的难点和关键点本课题的关键点在于对Sockets的理解和运用。Sockets是Windows下网络编程的规范,WindowsSockets是Windows下得到广