客户端服务器通信






2.39/5 (18投票s)
2006年1月17日
1分钟阅读

113700

9993
本文档介绍了使用套接字进行客户端-服务器通信的信息。
引言
本文档介绍了使用套接字进行客户端-服务器通信的信息。感谢 Ernest Laurentin 编写了一个名为 SocketComm
的优秀类,该类提供了在开发客户端-服务器应用程序中很有用的方法。
概述
图 I-1 显示了一种编程框架。左侧块代表客户端应用程序。其余部分代表服务器应用程序。如果客户端应用程序想要向服务器发送/接收数据,客户端需要创建一个套接字(客户端套接字)并使用此套接字与服务器通信。在服务器端,有两种类型的套接字。一个是监听套接字,负责处理来自新客户端的请求。另一个是服务套接字,其工作是处理现有客户端与服务器之间的所有通信。当新用户请求加入服务时,监听套接字将为该新用户创建一个新的服务套接字。服务套接字的功能类似于每个客户端的代表。换句话说,如果系统中存在 N 个用户,则服务器端将存在 N 个服务套接字。
服务器应用程序概述
服务器将首先设置服务。它将继续等待来自新用户的任何请求。如果授予新请求,服务器将创建一个新的服务套接字来服务该新用户。
监听请求的代码
DWORD WINAPI CallServerThread(LPVOID lpPtr) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) CSampleServerDlg* pThis = reinterpret_cast( lpPtr ); _ASSERTE( pThis != NULL ); SOCKET Soc; while(TRUE) { TCHAR szBuf[MAX_PATH] = {0}; Soc = (SOCKET)pThis->m_hComm; fd_set fdRead = { 0 }; Soc = accept(Soc,0,0); DWORD dWW = GetLastError(); if(Soc != INVALID_SOCKET) { CString strTotClients = ""; pThis->m_hNewSocHandle = (HANDLE) Soc; pThis->UpdateUserInfo(); } Sleep(500); } return 0; }
服务套接字的代码
DWORD WINAPI ListeningThread(LPVOID lpPtr) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) TCHAR szBuf[MAX_PATH] = {0}; CListeningClass *pThis = reinterpret_cast(lpPtr); SOCKET Soc ; Soc = (SOCKET)pThis->m_hComm; if(Soc != INVALID_SOCKET) { while(TRUE) { int nRet = recv(Soc,szBuf,sizeof(szBuf),0); if(nRet != SOCKET_ERROR ) { if(!::IsWindowVisible(pThis->m_hWnd)) pThis->ShowWindow(SW_SHOW); CString strText = szBuf; pThis->m_Recv.SetWindowText(strText); } Sleep(100); } } return 0; }
结束时终止线程的代码
void CListeningClass::TerminateThread() { DWORD dwExitCode = 0; while(TRUE) { ::TerminateThread(m_handle,dwExitCode); if(::GetExitCodeThread(m_handle,&dwExitCode)) { if (dwExitCode !=STILL_ACTIVE) { break; } else Sleep(10); } } }
演示工作原理
- 启动服务器应用程序并单击“启动服务器”。现在,应用程序开始监听客户端。
- 启动客户端应用程序,指定 IP 地址,然后单击“连接”。