08 一个连接一个线程模型 正因为最原始的服务器结构不支持并发随着计算机引入多线程模型后软件开发者想出了另外一种服务器结构即给每一个客户端连接创建一个线程这样多个线程就可以并行执行了可以同时为多个客户端服务。示例代码如下//侦听线程 UINT WINAPI MyMainThread(LPVOID lPvoid) { LOG_NORMAL(Start MyMainThread successfully, ThreadID %u., ::GetCurrentThreadId()); UINT nThreadID 0; SOCKET sListenSocket (SOCKET)lPvoid; SOCKET sClientSocket 0; while (1) { //等待客户连接 sockaddr_in clientAddr { 0 }; int clientAddrLength sizeof(clientAddr); if ((sClientSocket accept(sListenSocket, (struct sockaddr*)clientAddr, clientAddrLength)) INVALID_SOCKET) break; LOG_NORMAL(New client connected: %s:%d, inet_ntoa(clientAddr.sin_addr), clientAddr.sin_port); //启动客户签到线程 _beginthreadex(NULL, 0, MyChildThread, (LPVOID)sClientSocket, 0, nThreadID); } closesocket(sListenSocket); return 0; }//接收连接线程 UINT WINAPI MyChildThread(LPVOID lPvoid) { LOG_NORMAL(Start MyChildThread successfully, ThreadID %u., ::GetCurrentThreadId()); //交易处理 SOCKET sClientSocket (SOCKET)lPvoid; CLIENTITEM clientItem { 0 }; int nCmd HandleClientMain(sClientSocket, clientItem); LOG_NORMAL(Client cmd %d, nCmd); if (nCmd -1) closesocket(sClientSocket); else if (nCmd CONN_MAIN) LoginTrans(sClientSocket, clientItem); else InterTrans(sClientSocket, clientItem, nCmd); return 0; }上述代码中在某个线程MyMainThread中可以是主线程也可以是非主线程调用accept接受客户端连接成功接受连接后为每一个新连接创建一个工作线程MyChildThread。当然为了能让工作线程可以正常处理所负责的连接上的来往数据利用线程函数参数将 socket 句柄传给工作线程注意上述代码中参数sClientSocket的传递方法。