在我们的处理函数中可以如下监听客户端的连接:
SOCKET listenSock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_port = htons(7788); sin.sin_addr.S_un.S_addr = INADDR_ANY; int nRet = bind( listenSock, (sockaddr*)&sin, (int)(sizeof(sin))); if ( nRet == SOCKET_ERROR ) { DWORD errCode = GetLastError(); return; } listen( listenSock, 5); int clientNum = 0; sockaddr_in clientAddr; int nameLen = sizeof( clientAddr ); while( clientNum < FD_SETSIZE ) { SOCKET clientSock = accept( listenSock, (sockaddr*)&clientAddr, &nameLen ); //hWnd为接收系统发送的消息的窗口句柄 WSAAsyncSelect( clientSock, hWnd, UM_SOCK_ASYNCRECVMSG, FD_READ | FD_CLOSE ); clientNum++; }
接下来,我们需要在我们的窗口添加对UM_SOCK_ASYNCRECVMSG消息的处理函数,在该函数中真正接收客户端发送过来的数据,在这个消息处理函数中的wparam参数表示的是客户端套接字,lparam参数表示的是发生的网络事件如:
SOCKET clientSock = (SOCKET)wParam; if ( WSAGETSELECTERROR( lParam ) ) { closesocket( clientSock ); return; } switch ( WSAGETSELECTEVENT( lParam ) ) { case FD_READ: { char recvBuffer[1024] = {‘\0‘}; int nRet = recv( clientSock, recvBuffer, 1024, 0 ); if ( nRet > 0 ) { szRecvMsg.AppendFormat(_T("Client %d Say:%s\r\n"), clientSock, recvBuffer ); } else { //client disconnect szRecvMsg.AppendFormat(_T("Client %d Disconnect!\r\n"), clientSock ); } } break; case FD_CLOSE: { closesocket( clientSock ); szRecvMsg.AppendFormat(_T("Client %d Disconnect!\r\n"), clientSock ); } break; }可以看到WsaAsyncSelect模型是非常简单的模型,它解决了普通select模型的问题,但是它最大的缺点就是它只能用在windows程序上,因为它需要一个接收系统消息的窗口句柄。
原文地址:http://blog.csdn.net/wljlwyq/article/details/40087185