计算机网络课设-基于TCP协议编程的网络聊天室.docx
《计算机网络课设-基于TCP协议编程的网络聊天室.docx》由会员分享,可在线阅读,更多相关《计算机网络课设-基于TCP协议编程的网络聊天室.docx(27页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、优质文本基于TCP协议编程的网络聊天室设计内容:基于TCP协议编程的方式,编写程序模拟网络聊天室的运行过程。设计要求:1. 采用C/S模式,基于TCP协议编程的方式,使得各个用户通过效劳器转发实现聊天的功能。2. 分为两大模块:客户端模块和效劳器端模块。3. 客户端模块的主要功能:1登陆功能:用户可以注册,然后选择效劳器登入聊天室。2显示用户:将在线用户显示在列表中。3接收信息:能接收其他用户发出的信息。4发送信息:能发出用户要发出的信息。4.效劳器端模块的主要功能:1)检验登陆信息:检查登陆信息是否正确,并向客户端返回登陆信息,如信息正确。就允许用户登陆。2)显示在线状态:将该用户的状态发给
2、各在线用户。3)转发聊天信息:将消息转发给所有在线的用户。5. 编程语言不限。一、 需求分析此程序主要分为两局部:效劳器端和客户端。效劳器端用于提供一个网络端口,等待客户端发出请求,登录到此效劳端,然后进行网络通讯和消息的转发;客户端可通过效劳器端的IP地址发送连接请求,然后登陆聊天室。在效劳器端的成员列表栏中会显示在线的所有人名单,有人退出聊天室,成员列表会自动除名。整个程序的主体使用了CSocket类的方法,实现了网络通讯聊天。整个程序设计为两个局部:效劳器(SpeakerServer)和客户端 (SpeakerClient)。 多人聊天的关键在于要将每个客户端发送过来的消息分发给所有其他
3、客户端,为了解决这个问题,在效劳器程序中建立一个套接口链表,用来保存所有与客户端建立了连接的效劳端口。设计原理:效劳器通过socket()系统调用创立一个Socket数组后设定了接受连接客户的最大数目,与指定的本地端口绑定bind(),就可以在端口进行侦听listen()。如果有客户端连接请求,那么在数组中选择一个空socket,将客户端地址赋给这个socket,然后登陆成功的客户就可以在效劳器上聊天了。客户端程序相对简单,只要建立一个socket与效劳器端连接,成功后通过这个socket来发送和接收就可以了。效劳器端功能:1、 初始化socket,创立效劳器端。2、 维护一个链表,保存所有用
4、户的IP地址,端口信息。3、 接受用户传送来的聊天信息,然后向链表中的所用用户转发。4、 接受用户传送来的连接判断命令,并向用户发出响应命令。客户端功能:客户端界面上的两个文本框,一个用于显示接受的聊天信息,一个用来接受用户输入的聊天信息。当按下“发送按钮时将信息发送给效劳器。一、 概要设计: 效劳器 客户端 设计流程图二、 详细设计:效劳器端:1、启动效劳器代码:/效劳器启动时,先创立套接字并绑定端口,再监听此端口。void CSpeakerServerDlg:OnBnClickedStart()UINT uPort = GetDlgItemInt(IDC_PORT);/创立套接字if (
5、!m_TCPSocketListen.Create(uPort) )m_TraceRichEdit.TraceString(TEXT(绑定监听端口失败,请确认该端口没有被其它程序占用),TraceLevel_Warning);return;/监听套接字if( !m_TCPSocketListen.Listen() )m_TraceRichEdit.TraceString(TEXT(监听失败),TraceLevel_Warning);return;UINT uMaxConnect = GetDlgItemInt(IDC_MAX);/设置接口m_TCPSocketListen.SetTCPSock
6、etService(this);/更新界面m_TraceRichEdit.TraceString(TEXT(效劳器启动成功),TraceLevel_Normal);GetDlgItem(IDC_START)-EnableWindow(FALSE);GetDlgItem(IDC_STOP)-EnableWindow(TRUE);2、监听端口,收到连接请求,接受的代码:/先检验是否在效劳器的最大连接限制内,假设在,那么获取当前客户的IP地址和端口等信息,插入链表中。/为什么要限制连接人数?因为TCP连接是相当占资源的,假设不限制连接人数,效劳器的资源不够分配。void CSpeakerServer
7、Dlg:OnAccept()/承载能力if ( m_TCPSocketItemMap.size() GetDlgItemInt(IDC_MAX) )m_TraceRichEdit.TraceString(TEXT(效劳器承载人数已满,已过滤其他连接),TraceLevel_Warning);return;/绑定套接字CTCPSocketService *pTCPSocketConnect = new CTCPSocketService; try SOCKADDR_INSocketAddr; int nBufferSize = sizeof(SocketAddr); /连接 m_TCPSocke
8、tListen.Accept(*pTCPSocketConnect,(SOCKADDR *) &SocketAddr, &nBufferSize); if (pTCPSocketConnect-m_hSocket = INVALID_SOCKET) throw TEXT(无效的连接套接字); /获取客户端IP pTCPSocketConnect-m_dwClientAddr = SocketAddr.sin_addr.S_un.S_addr; pTCPSocketConnect-SetTCPSocketService(this);/绑定数据bool bActive = true;CTCPSoc
9、ketItemMap:iterator iter = m_TCPSocketItemMap.begin();for (;iter!= m_TCPSocketItemMap.end();iter+)if ( pTCPSocketConnect-m_hSocket = iter-first )bActive = false;break;/插入客户数据if ( bActive )tagBindParameter *pBindParameter = new tagBindParameter;pBindParameter-pTCPSocketService = pTCPSocketConnect;pBi
10、ndParameter-dwUserID = 0;m_TCPSocketItemMap.insert(pair(pTCPSocketConnect-m_hSocket,pBindParameter); catch (.) if (pTCPSocketConnect-m_hSocket != INVALID_SOCKET)pTCPSocketConnect-Close(); 3、接收并检验数据的代码:void CSpeakerServerDlg:OnReceive(SOCKET hSocket)BYTE cbDataBufferSOCKET_TCP_BUFFER;CTCPSocketItemMa
11、p:iterator iter = m_TCPSocketItemMap.find(hSocket);if ( iter = m_TCPSocketItemMap.end() ) return;/接收数据iter-second-pTCPSocketService-Receive(cbDataBuffer,CountArray(cbDataBuffer) );/解析数据TCP_Command * pCommand=(TCP_Command *)cbDataBuffer;/解释数据WORD wPacketSize = pCommand-wPacketSize;WORD wDataSize = wP
12、acketSize-sizeof(TCP_Command);/数据包效验if ( wPacketSize SOCKET_TCP_BUFFER+sizeof TCP_Command )m_TraceRichEdit.TraceString(TEXT(数据包太大,已拒绝),TraceLevel_Warning);return;/子消息处理事件if( !OnEventTCPSocketRead(hSocket,pCommand-wMainCmdID,pCommand-wSubCmdID,pCommand+1,wDataSize) )BYTE * pClientIP=(BYTE *)&iter-sec
13、ond-pTCPSocketService-m_dwClientAddr;m_TraceRichEdit.TraceString(TraceLevel_Warning,TEXT(收到伪数据包或未处理的数据包,wMainCmdID:%d,wSubCmdID:%d,来源IP:%d.%d.%d.%d),pCommand-wMainCmdID,pCommand-wSubCmdID,pClientIP0,pClientIP1,pClientIP2,pClientIP3);return;4、群发登录消息和用户发送的消息代码:/效劳器收到客户的消息之后会将收到的消息发送给链表之中除了发送客户之外的所有客户。
14、bool CSpeakerServerDlg:OnEventTCPSocketRead( SOCKET hSocket,WORD wMainCmdID, WORD wSubCmdID, VOID * pData, WORD wDataSize )/获取绑定套接字CTCPSocketItemMap:iterator iter = m_TCPSocketItemMap.find(hSocket);if ( iter = m_TCPSocketItemMap.end() ) return false;CTCPSocketService *pTCPSocketService = iter-second
15、-pTCPSocketService;switch ( wMainCmdID )case MDM_GP_LOGON:if ( wSubCmdID = SUB_CS_LOGON )/效验数据ASSERT( wDataSize = sizeof CMD_CS_LOGON );if ( wDataSize != sizeof CMD_CS_LOGON ) return false;/获取数据CMD_CS_LOGON *pUserLogon = (CMD_CS_LOGON*)pData;m_TraceRichEdit.TraceString(TraceLevel_Normal,TEXT(%s登陆效劳器
16、),pUserLogon-szUserName);tagUserData *pUserData = new tagUserData;/随机给用户分配一个UserID,UserID一般存储于数据库中,是一个独一无二的数字,/一般在数据库表中设为主键,是整个游戏或者软件识别用户的唯一依据,这里我们没有涉及到数据库,暂时随机取一个数值代替/其次,我们应该通过数据库SQL语句查询或者存储过程等方法,或在数据库中做密码的效验也好,/或在查询到用户的密码在效劳器中进行判断也好,不管什么方法,此处一般需要进行用户密码的效验,这样才可以判定用户是否可以登陆了pUserData-dwUserID = GetTi
17、ckCount();_sntprintf_s(pUserData-szUserName,CountArray(pUserData-szUserName),pUserLogon-szUserName);_sntprintf_s(pUserData-szPassWord,CountArray(pUserData-szPassWord),pUserLogon-szPassWord);/更新绑定数据CTCPSocketItemMap:iterator iter = m_TCPSocketItemMap.find(hSocket);if ( iter != m_TCPSocketItemMap.end(
18、) )iter-second-dwUserID = pUserData-dwUserID;/群发登陆消息SendUserItem(NULL,pUserData);/发送在线用户CUserItemArray:iterator pUserItemSend = m_pUserManager-GetUserItemArray()-begin();for (;pUserItemSend!=m_pUserManager-GetUserItemArray()-end();pUserItemSend+ )SendUserItem(pTCPSocketService,pUserItemSend-second);
19、/插入数据m_pUserManager-InsertUserItem(pUserData);return true;break;case MDM_GP_USER:if ( wSubCmdID = SUB_CS_USERT_CHAT )/获取数据CMD_CS_CHATMSG *pCHATMSG = (CMD_CS_CHATMSG*)pData;/这里其实需要做很多的效验,如dwSendUserID的有效性,字符串是否为空等,这里就不做这些效验了CMD_SC_CHATMSG _SC_CHATMSG;ZeroMemory(&_SC_CHATMSG,sizeof _SC_CHATMSG);/获取时间G
20、etLocalTime(&_SC_CHATMSG.SystemTime);_sntprintf_s(_SC_CHATMSG.szSendUserName,CountArray(_SC_CHATMSG.szSendUserName),m_pUserManager-GetUserName(iter-second-dwUserID);_sntprintf_s(_SC_CHATMSG.szDescribe,CountArray(_SC_CHATMSG.szDescribe),pCHATMSG-szDescribe);SendDataBatch(MDM_GP_USER,SUB_CS_USERT_CHAT
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 计算机网络 基于 TCP 协议 编程 网络 聊天室
限制150内