客户端服务器通信






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 地址,然后单击“连接”。
