代码如下: #include <stdio.h> #include <WinSock2.h> #include <process.h> #pragma comment(lib, "ws2_32.lib") HANDLE g_hEvent = NULL; CRITICAL_SECTION g_crs; void myPrintf(const char* psz1, ...) { ::EnterCriticalSection(&g_crs); va_list arg; va_start(arg, psz1); vprintf(psz1, arg); va_end(arg); ::LeaveCriticalSection(&g_crs); } unsigned __stdcall ClientProc(void* parm) { WSADATA wsData; SOCKET skClient; SOCKADDR_IN addrServ; char msg[1024]={0}; fd_set rFSet; int iRet = WSAStartup(MAKEWORD(2, 2), &wsData); if (iRet != 0) { myPrintf(">>> client WSAStartup fail\n"); return 1; } skClient = socket(AF_INET, SOCK_STREAM, 0); myPrintf(">>> client socket %d\n", skClient); addrServ.sin_family = AF_INET; addrServ.sin_port = htons(6000); addrServ.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); WaitForSingleObject(g_hEvent, INFINITE); iRet = connect(skClient, (sockaddr*)&addrServ, sizeof(SOCKADDR_IN)); if (iRet != 0) { myPrintf(">>> client connect fail\n"); goto end; } while (true) { ::EnterCriticalSection(&g_crs); printf(">>> client please input send msg: "); scanf("%s", msg); ::LeaveCriticalSection(&g_crs); iRet = send(skClient, msg, sizeof(msg)/sizeof(char), 0); if (iRet == SOCKET_ERROR) { myPrintf(">>> client send fail\n"); break; } FD_ZERO(&rFSet); FD_SET(skClient, &rFSet); iRet = select(skClient + 1, &rFSet, NULL, NULL, NULL); if (iRet <= 0) { myPrintf(">>> client select fail\n"); break; } memset(msg, 0, sizeof(msg)/sizeof(char)); iRet = recv(skClient, msg, sizeof(msg)/sizeof(char), 0); if (iRet == SOCKET_ERROR) { myPrintf(">>> client recv fail\n"); break; } if (strcmp(msg, "quit") == 0) { myPrintf(">>> client quit\n"); break; } else { myPrintf(">>> client recv: %s\n", msg); } } closesocket(skClient); end: myPrintf(">>> client exit\n"); WSACleanup(); return 0; } unsigned __stdcall ServerProc(void* param) { WSADATA wsData; int iRet = WSAStartup(MAKEWORD(2, 2), &wsData); if (iRet != 0) { myPrintf("server WSAStartup fail\n"); return 1; } char msg[1024]={0}; int len = sizeof(SOCKADDR_IN); SOCKET skServer, skClient; fd_set rfSet; skServer = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); SOCKADDR_IN addrServer, addrClient; addrServer.sin_family = AF_INET; addrServer.sin_port = htons(6000); addrServer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); iRet = bind(skServer, (const sockaddr*)&addrServer, sizeof(addrServer)); if (iRet != 0) { myPrintf(">>> server bind fail\n"); goto end; } iRet = listen(skServer, 5); if (iRet == -1) { myPrintf(">>> server listen fail\n"); goto end; } SetEvent(g_hEvent); skClient = accept(skServer, (sockaddr*)&addrClient, &len); if (skClient == -1) { myPrintf(">>> no client connect to server\n"); goto end; } myPrintf(">>> client %d connect to server success\n", skClient); while (true) { FD_ZERO(&rfSet); FD_SET(skClient, &rfSet); iRet = select(skClient + 1, &rfSet, NULL, NULL, NULL); if (iRet <= 0) { myPrintf(">>> server select fail\n"); break; } memset(msg, 0, sizeof(msg)/sizeof(char)); iRet = recv(skClient, msg, sizeof(msg)/sizeof(char), 0); if (iRet == SOCKET_ERROR) { myPrintf(">>> server recv fail\n"); break; } else { myPrintf(">>> server recv: %s\n", msg); ::EnterCriticalSection(&g_crs); myPrintf(">>> server please input command: "); memset(msg, 0, sizeof(msg)/sizeof(char)); scanf("%s", msg); ::LeaveCriticalSection(&g_crs); iRet = send(skClient, msg, sizeof(msg)/sizeof(char), 0); if (iRet == SOCKET_ERROR) { myPrintf(">>> server send fail\n"); break; } } } end: closesocket(skServer); WSACleanup(); myPrintf(">>> server exit\n"); return 0; } int _tmain(int argc, _TCHAR* argv[]) { InitializeCriticalSection(&g_crs); g_hEvent = CreateEventA(NULL, TRUE, FALSE, "MMClient##Event"); HANDLE hClient = (HANDLE)_beginthreadex(NULL, 0, ClientProc, NULL, 0, NULL); HANDLE hServer = (HANDLE)_beginthreadex(NULL, 0, ServerProc, NULL, 0, NULL); WaitForSingleObject(hClient, INFINITE); WaitForSingleObject(hServer, INFINITE); system("@pause"); return 0; }