网上聊天实验报告.doc_第1页
网上聊天实验报告.doc_第2页
网上聊天实验报告.doc_第3页
网上聊天实验报告.doc_第4页
网上聊天实验报告.doc_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

网络聊天室程序 -实验报告信科03(1)班 楼欢庆 I03630117聊天室程序的设计说明1. 实现思想在Internet上的聊天室程序一般都是以服务器提供服务端连接响应,使用者通过客户端程序登录到服务器,就可以与登 录在同一服务器上的用户交谈,这是一个面向连接的通信过程。因此 ,程序要在TCP/IP环境下,实现服务器端和客户端两部分程序 。实现语言C+,开发环境VC/MFC。2.功能模块总纲2.1服务器端工作流程服务器端通过socket()系统调用创建一个Sock et数组后(即设定了接受连接客户的最大数目),与指定的本地端 口绑定bind(),就可以在端口进行侦听listen()。如果有客户端连接请求,则在数组中选择一个空Socket,将客户端地址赋给这个Socket。然后登录成功的客户就可以在服务器上聊天了。实现方式采用异步非阻塞机制。2.2客户端工作流程客户端程序相对简单,只需要建立一个Socket 与服务器端连接,成功后通过这个Socket来发送和接收数据就 可以了。2.3 C/S实现过程服务器端: 首先使用WSAStartup函数来初始化网络环境。 调用socket(AF_INET,SOCK_STREAM,0)函数来创建一个套接字。 调用bind函数将本地地址与刚建立的套接字关联起来。 调用listen函数监听发向该套接字的连接请求。 客户端的连接请求放在连接请求队列里,服务器调用accept函数从连接请求队列中取出第一个请求,创建一个为之服务的新的套接字,该套接字处理所有与该客户交互操作的信息。而服务器进程的监听套接字这时继续处理来自其他客户的连接请求,直到因队列空而等待新的连接请求的到来。 调用closesocket()关闭监听套接字,释放套接字资源。 调用WSACleanup函数释放相应资源。客户端: 首先使用WSAStartup函数来初始化网络环境。 调用socket(AF_INET,SOCK_STREAM,0)函数来创建一个套接字。 调用connect函数连接远程服务器,以请求服务。 服务器相应连接请求后,此时客户端进程开始与服务器的交互操作,直到请求结束为止。 调用closesocket()关闭监听套接字,释放套接字资源。 调用WSACleanup函数释放相应资源。3.流程图设计4.模块设计主要函数功能说明Client: 使用基于对话框的模式进行编写用户登入模块:主要功能:进行服务器IP地址的输入。进行通讯端口号的输入(默认5000)昵称的输入(默认guest)OnOK()实现各编辑框信息的保存(相应地用变量保存输入的信息)OnCancel()撤销操作用户聊天模块:主要功能:OnLogin()调用用户登入模块。并进行服务器请求连接OnSocketConnect() OnSocketConnect()函数:进行Socket数据库版本的协商WSAStartup(),并确认服务器IP输入格式是否正确。同时调用socket()创建套接字用于连接。初始化服务器SOCKADDR_IN的各参数的值。然后调用connect()进行正式的服务器连接。然后使用异步WSAAsyncSelect()函数处理WM_SOCKET_READ消息(通过消息处理函数OnSocketRead()接收其他用户发到服务器的消息。 OnLogout()调用WSACleanup()和closesocket()关闭套接字和套接字库。OnSocketSend()调用send()通过通信端口将消息发送给服务器(某种意义上讲,发送给其他用户)。Server:基于单文档进行编写主要功能:OnServerOpen()函数:WSAStartup()初始化套接字库及版本协商。Gethostname()获取本地主机地址作为服务器。调用socket()创建服务器套接字,同时初始化各参数。然后进行bind()操作。将服务器端进行绑定。同时用WSAAsyncSelect()对请求连接的客户机消息WM_SERVER_ACCEPT(使用消息处理函数OnServerAccept()进行相应处理。最后用liston()监听到达的客户端请求。OnServerAccept()函数:调用accept()进行对客户端请求的回应。即分配一个新的m_aClientSocket,相应地为其异步处理消息通过WSAAsyncSelect()中对WM_CLIENT_READCLOSE消息的处理。服务器发送消息到客户机通知连接建立。OnClientReadClose()处理WM_CLIENT_READCLOSE消息。FD_READ时调用OnClientRead()进行处理,FD_CLOSE时调用OnClientClose()时进行处理。OnClientRead()调用recv()接收从客户端发送过来的消息,同时调用OnServerBroadcast()将这个信息广播到各个连接到该服务器的客户端。OnClientClose()关闭退出用户的socket。OnServerBroadcast()函数:向连接在服务器上的所有客户广播消息。使用了send()函数。.主要代码分析:Server:void CServerView:OnServerOpen() /服务器开启 WSADATA wsaData;int iErrorCode;char chLocalInfo64;if (WSAStartup(WINSOCK_VERSION, &wsaData)MessageBeep(MB_ICONSTOP);MessageBox(Winsock could not be initialized!, AfxGetAppName(), MB_OK|MB_ICONSTOP);WSACleanup();return; elseWSACleanup();if (gethostname(chLocalInfo, sizeof(chLocalInfo)ReportWinsockErr(nCould not resolve local host!nAre you on-line?n);return;CString csWinsockID = n=服务器已经开启,端口号: ;csWinsockID += itoa(m_pDoc-m_nServerPort, chLocalInfo, 10);csWinsockID += n;csWinsockID += wsaData.szDescription;csWinsockID += n;PrintString(csWinsockID);m_pDoc-m_hServerSocket = socket(PF_INET, SOCK_STREAM, DEFAULT_PROTOCOL);if (m_pDoc-m_hServerSocket = INVALID_SOCKET) ReportWinsockErr(Could not create server socket.);return; m_pDoc-m_sockServerAddr.sin_family = AF_INET;m_pDoc-m_sockServerAddr.sin_addr.s_addr = INADDR_ANY; m_pDoc-m_sockServerAddr.sin_port = htons(m_pDoc-m_nServerPort);if (bind(m_pDoc-m_hServerSocket, (LPSOCKADDR)&m_pDoc-m_sockServerAddr, sizeof(m_pDoc-m_sockServerAddr) = SOCKET_ERROR) ReportWinsockErr(Could not bind server socket.);return; iErrorCode = WSAAsyncSelect(m_pDoc-m_hServerSocket, m_hWnd, WM_SERVER_ACCEPT, FD_ACCEPT);if (iErrorCode = SOCKET_ERROR) ReportWinsockErr(WSAAsyncSelect failed on server socket.);return;if (listen(m_pDoc-m_hServerSocket, QUEUE_SIZE) = SOCKET_ERROR) ReportWinsockErr(Server socket failed to listen.);m_pParentMenu-EnableMenuItem(ID_SERVER_OPEN, MF_ENABLED);return; PrintString(=服务器套接字初始化完成 - 等待连接.nn);m_bServerIsOpen = TRUE;return;LRESULT CServerView:OnServerAccept(WPARAM wParam, LPARAM lParam)/处理服务器接收WM_SERVER_ACCEPT消息的函数 int iErrorCode;int nLength = sizeof(SOCKADDR);int i;if (WSAGETSELECTERROR(lParam)ReportWinsockErr(Error detected on entry into OnServerAccept.);return 0L;if (WSAGETSELECTEVENT(lParam) = FD_ACCEPT)for(i=0;(i一个客户连接成功!n);m_aClientSocketi = accept(m_pDoc-m_hServerSocket, (LPSOCKADDR)&m_sockClientAddr, (LPINT)&nLength);if (m_aClientSocketi = INVALID_SOCKET)ReportWinsockErr(Server socket failed to accept connection.);return 0L;CString csDottedDecimal = 一个客户进行了连接 ;csDottedDecimal += inet_ntoa(m_sockClientAddr.sin_addr);csDottedDecimal += n;PrintString(=+csDottedDecimal);WSAAsyncSelect(m_aClientSocketi,m_hWnd,WM_CLIENT_READCLOSE,FD_READ|FD_CLOSE);CString csText = 服务器连接成功;LPSTR lpszResponse = csText.GetBuffer(1000);iErrorCode = send( m_aClientSocketi, lpszResponse, lstrlen(lpszResponse), NO_FLAGS); if (iErrorCode = SOCKET_ERROR)ReportWinsockErr(Error sending response to client.);/else/PrintString(Response sent!n);/OnClientClose();return 0L;LRESULT CServerView:OnClientReadClose(WPARAM wParam, LPARAM lParam)/处理WM_CLIENT_READCLOSE消息函数switch (WSAGETSELECTEVENT(lParam)case FD_READ:OnClientRead(wParam,lParam);break;case FD_CLOSE:OnClientClose(wParam,lParam);break;return 0L;LRESULT CServerView:OnClientRead(WPARAM wParam, LPARAM lParam)/处理客户端发送过来的消息int iBytesRead;int iBufferLength;int iEnd;int iSpaceRemaining;char chIncomingDataBuffer1024;int i;for(i=0;(iMAXClient)&(m_aClientSocketi!=wParam);i+)if(i=MAXClient) return 0L;iBufferLength = iSpaceRemaining = sizeof(chIncomingDataBuffer);iEnd = 0;iSpaceRemaining -= iEnd;iBytesRead = recv(m_aClientSocketi, (LPSTR)(chIncomingDataBuffer+iEnd), iSpaceRemaining, NO_FLAGS);iEnd+=iBytesRead;if (iBytesRead = SOCKET_ERROR)ReportWinsockErr(OnClientRead recv reported a socket error. );chIncomingDataBufferiEnd = 0;if (lstrlen(chIncomingDataBuffer) != 0)PrintString(chIncomingDataBuffer);OnServerBroadcast(chIncomingDataBuffer);else;/ Since Windows send notification of FD_READ and FD_CLOSE,/ assume the client has closed the connection if zero bytes/ are received. The program uses a blocking socket, which means if the/ connection were still open, recv() would wait for data./OnClientClose();return(0L);LRESULT CServerView:OnClientClose(WPARAM wParam, LPARAM lParam)/处理客户端退出的消息 int iErrorCode,i;if (WSAGETASYNCERROR(lParam) ReportWinsockErr(Error detected on entry into OnClientClose);for(i=0;(i客户端套接字成功关闭, 等待下一个客户到达!nn);return 0L;LRESULT CServerView:OnServerBroadcast(char acSendBuff)/向各客户端广播的消息函数int i;for(i=0;iEnableWindow(FALSE);GetDlgItem(IDC_LOGOUT)-EnableWindow(TRUE);GetDlgItem(IDC_SEND)-EnableWindow(TRUE);GetDlgItem(IDC_EDIT_SEND)-EnableWindow(TRUE);UpdateData(FALSE);LRESULT CClientDlg:OnSocketRead(WPARAM wParam,LPARAM lParam)/处理WM_SOCKET_READ消息的函数int iBytesRead;int iBufferLength;int iEnd;int iSpaceRemaining;char chIncomingDataBuffer100;iBufferLength = iSpaceRemaining = sizeof(chIncomingDataBuffer);iEnd = 0;iSpaceRemaining -= iEnd;iBytesRead = recv(m_hSocket, (LPSTR)(chIncomingDataBuffer+iEnd), iSpaceRemaining, 0);iEnd+=iBytesRead;if (iBytesRead = SOCKET_ERROR)ReportWinsockErr(OnClientRead recv reported a socket error. );chIncomingDataBufferiEnd = 0;if (lstrlen(chIncomingDataBuffer) != 0)m_csRead=m_csRead+rn+chIncomingDataBuffer;GetDlgItem(IDC_EDIT_READ)-SetWindowText(LPCSTR)m_csRead);CEdit *pEdit

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论