回声服务器端:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <WinSock2.h> 4 5 #define BUF_SIZE 1024 6 void ErrorHandling(char *message); 7 void CompressSockets(SOCKET hSockArr[], int idx, int total); 8 void CompressEvents(WSAEVENT hEventArr[], int idx, int total); 9 10 int main(int argc, char *argv[]) 11 { 12 if (argc != 2) { 13 printf("Usage : %s <port>\n", argv[0]); 14 exit(1); 15 } 16 17 WSADATA wsaData; 18 SOCKET hServSock, hClntSock; 19 SOCKADDR_IN servAdr, clntAdr; 20 21 SOCKET hSockArr[WSA_MAXIMUM_WAIT_EVENTS]; 22 WSAEVENT hEventArr[WSA_MAXIMUM_WAIT_EVENTS]; 23 WSAEVENT newEvent; 24 WSANETWORKEVENTS netEvents; 25 26 int numOfClntSock = 0; 27 int strLen; 28 int posInfo, startIdx; 29 int clntAdrLen; 30 char msg[BUF_SIZE]; 31 32 if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) 33 ErrorHandling("WSAStartup() error."); 34 35 hServSock = socket(PF_INET, SOCK_STREAM, 0); 36 if (hServSock == INVALID_SOCKET) 37 ErrorHandling("socket() error."); 38 39 memset(&servAdr, 0, sizeof(servAdr)); 40 servAdr.sin_family = AF_INET; 41 servAdr.sin_addr.s_addr = htonl(INADDR_ANY); 42 servAdr.sin_port = htons(atoi(argv[1])); 43 44 if (bind(hServSock, (SOCKADDR*)&servAdr, sizeof(servAdr)) == SOCKET_ERROR) 45 ErrorHandling("bind() error."); 46 if (listen(hServSock, 5) == SOCKET_ERROR) 47 ErrorHandling("listen() error."); 48 49 newEvent = WSACreateEvent(); 50 if (WSAEventSelect(hServSock, newEvent, FD_ACCEPT) == SOCKET_ERROR) 51 ErrorHandling("WSAEventSelect() error."); 52 53 hSockArr[numOfClntSock] = hServSock; 54 hEventArr[numOfClntSock] = newEvent; 55 numOfClntSock++; 56 printf("Server start...\n"); 57 while (1) 58 { 59 posInfo = WSAWaitForMultipleEvents(numOfClntSock, hEventArr, FALSE, WSA_INFINITE, FALSE); 60 startIdx = posInfo - WSA_WAIT_EVENT_0; 61 for (int i = startIdx; i < numOfClntSock; i++){ 62 int sigEventIdx = WSAWaitForMultipleEvents(1, &hEventArr[i], TRUE, 0, FALSE); 63 if (sigEventIdx == WSA_WAIT_FAILED || sigEventIdx == WSA_WAIT_TIMEOUT){ 64 continue; 65 } 66 else{ 67 sigEventIdx = i; 68 WSAEnumNetworkEvents(hSockArr[sigEventIdx], hEventArr[sigEventIdx], &netEvents); 69 if (netEvents.lNetworkEvents & FD_ACCEPT){ // 客户端请求连接 70 if (netEvents.iErrorCode[FD_ACCEPT_BIT] != 0) 71 { 72 printf("Accept error.\n"); 73 break; 74 } 75 clntAdrLen = sizeof(clntAdr); 76 hClntSock = accept(hSockArr[sigEventIdx], (SOCKADDR*)&clntAdr, &clntAdrLen); 77 newEvent = WSACreateEvent(); 78 WSAEventSelect(hClntSock, newEvent, FD_READ | FD_CLOSE); 79 80 hEventArr[numOfClntSock] = newEvent; 81 hSockArr[numOfClntSock] = hClntSock; 82 numOfClntSock++; 83 printf("connected new client...\n"); 84 } 85 if (netEvents.lNetworkEvents & FD_READ){ // 接收数据 86 if (netEvents.iErrorCode[FD_READ_BIT] != 0) 87 { 88 printf("Read error\n"); 89 break; 90 } 91 strLen = recv(hSockArr[sigEventIdx], msg, sizeof(msg), 0); 92 send(hSockArr[sigEventIdx], msg, strLen, 0); 93 } 94 if (netEvents.lNetworkEvents & FD_CLOSE){ // 断开连接 95 if (netEvents.iErrorCode[FD_CLOSE_BIT] != 0) 96 { 97 printf("Close Error.\n"); 98 break; 99 } 100 WSACloseEvent(hEventArr[sigEventIdx]); 101 closesocket(hSockArr[sigEventIdx]); 102 103 numOfClntSock--; 104 CompressSockets(hSockArr, sigEventIdx, numOfClntSock); 105 CompressEvents(hEventArr, sigEventIdx, numOfClntSock); 106 } 107 } 108 } 109 } 110 WSACleanup(); 111 return 0; 112 } 113 114 void ErrorHandling(char *message) { 115 fputs(message, stderr); 116 fputc('\n', stderr); 117 } 118 119 void CompressSockets(SOCKET hSockArr[], int idx, int total){ 120 for (int i = idx; i < total; i++) 121 hSockArr[i] = hSockArr[i + 1]; 122 } 123 124 void CompressEvents(WSAEVENT hEventArr[], int idx, int total){ 125 for (int i = idx; i < total; i++) 126 hEventArr[i] = hEventArr[i + 1]; 127 }
客户端:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #pragma warning(disable:4996) 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <string.h> 5 #include <winsock2.h> 6 7 #define BUF_SIZE 1024 8 void ErrorHandling(char *message); 9 10 int main(int argc, char* argv[]) { 11 if (argc != 3) { 12 printf("Usage : %s <IP> <port>\n", argv[0]); 13 exit(1); 14 } 15 16 WSADATA wsaData; 17 SOCKET sock; 18 SOCKADDR_IN serverAddr; 19 char message[BUF_SIZE]; 20 int sLen, recvLen; 21 22 if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) 23 ErrorHandling("WSAStartup() error"); 24 25 sock = socket(PF_INET, SOCK_STREAM, 0); 26 if (sock == INVALID_SOCKET) 27 ErrorHandling("socket() error"); 28 29 memset(&serverAddr, 0, sizeof(serverAddr)); 30 serverAddr.sin_family = AF_INET; 31 serverAddr.sin_addr.s_addr = inet_addr(argv[1]); 32 serverAddr.sin_port = htons(atoi(argv[2])); 33 34 if (connect(sock, (SOCKADDR*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) 35 ErrorHandling("connect() error"); 36 else 37 printf("Connected.......\n"); 38 while (1) 39 { 40 fputs("Input message(Q to quit):", stdout); 41 fgets(message, BUF_SIZE, stdin); 42 if (!strcmp(message, "q\n") || !strcmp(message, "Q\n")) 43 break; 44 sLen = send(sock, message, strlen(message), 0); 45 recvLen = 0; 46 while (recvLen < sLen) { 47 int cnt = recv(sock, message, BUF_SIZE - 1, 0); 48 if (cnt == -1) 49 ErrorHandling("ercv() error"); 50 recvLen += cnt; 51 } 52 message[recvLen] = 0; 53 printf("Message from server: %s\n", message); 54 } 55 closesocket(sock); 56 WSACleanup(); 57 return 0; 58 } 59 60 void ErrorHandling(char *message) { 61 fputs(message, stderr); 62 fputc('\n', stderr); 63 }