三-select模型
int select(int nfds, fd_set readfds, fd_set writefds, fd_set exceptfds, const struct timeval timeout);
参数
返回值
typedef struct fd_set { u_int fd_count; //fd_array数组中当前元素个数 SOCKET fd_array[FD_SETSIZE]; //socket数组 } fd_set;
1 #define _WINSOCK_DEPRECATED_NO_WARNINGS 2 3 #include <iostream> 4 #include <WinSock2.h> 5 #pragma comment(lib, "ws2_32.lib") 6 using namespace std; 7 const int nMajorVersion = 2; 8 const int nMinorVersion = 2; 9 10 int main() 11 { 12 DWORD dwVersion = MAKEWORD(nMajorVersion, nMinorVersion); 13 WSADATA wsaData; 14 int nStartRet = WSAStartup(dwVersion, &wsaData); 15 if (nStartRet != 0) 16 { 17 cout << "WSAStartup failed with error :" << nStartRet << endl; 18 return 1; 19 } 20 21 if (LOBYTE(wsaData.wVersion) != nMajorVersion || HIBYTE(wsaData.wVersion) != nMinorVersion) 22 { 23 cout << "version failed" << endl; 24 WSACleanup(); 25 return 1; 26 } 27 28 SOCKET sockServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 29 if (sockServer == INVALID_SOCKET) 30 { 31 cout << "socket create failed with code: "<< WSAGetLastError() << endl; 32 WSACleanup(); 33 return 1; 34 } 35 36 sockaddr_in addInfo; 37 addInfo.sin_family = AF_INET; 38 addInfo.sin_port = htons(12345); 39 addInfo.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); 40 int nBindRet = bind(sockServer, reinterpret_cast<sockaddr*>(&addInfo), sizeof(addInfo)); 41 if (SOCKET_ERROR == nBindRet) 42 { 43 cout << "bind failed with code: " << WSAGetLastError() << endl; 44 closesocket(sockServer); 45 WSACleanup(); 46 return 1; 47 } 48 49 int nListenRet = listen(sockServer, SOMAXCONN); 50 if (SOCKET_ERROR == nBindRet) 51 { 52 cout << "bind failed with code: " << WSAGetLastError() << endl; 53 closesocket(sockServer); 54 WSACleanup(); 55 return 1; 56 } 57 58 fd_set allSockets; 59 FD_ZERO(&allSockets); 60 FD_SET(sockServer, &allSockets); 61 struct timeval tv = { 3,0 }; 62 63 while (1) 64 { 65 fd_set tmpAllSockets = allSockets; 66 int nSelectRet = select(0, &tmpAllSockets, NULL, NULL, &tv); 67 if(nSelectRet == 0) continue; //超时 68 else if (nSelectRet == -1) //出错 69 { 70 cout << "select failed with code: " << WSAGetLastError() << endl; 71 break; 72 } 73 else if (nSelectRet > 0) 74 { 75 for (int i = 0; i < tmpAllSockets.fd_count; i++) 76 { 77 SOCKET socketID = tmpAllSockets.fd_array[i]; 78 79 if (socketID == sockServer) 80 { 81 SOCKET socketClient = accept(socketID, NULL, NULL); 82 if (socketClient == INVALID_SOCKET) 83 continue; 84 85 FD_SET(socketClient, &allSockets); 86 } 87 else 88 { 89 char buf[1024] = { 0 }; 90 int nRecvRet = recv(socketID, buf, 1024, 0); 91 if (nRecvRet == 0) //客户端断开连接 92 { 93 FD_CLR(socketID, &allSockets); 94 closesocket(socketID); 95 continue; 96 } 97 else if (nRecvRet > 0) 98 { 99 cout << socketID << " : " << buf << endl; 100 send(socketID, "我收到了你发送的数据!", sizeof("我收到了你发送的数据!"), 0); 101 } 102 else if (nRecvRet == SOCKET_ERROR) 103 { 104 int nError = WSAGetLastError(); 105 if (nError == 10054) 106 { 107 FD_CLR(socketID, &allSockets); 108 closesocket(socketID); 109 continue; 110 } 111 else 112 cout << "recv error." << endl; 113 } 114 } 115 } 116 } 117 } 118 119 for (int i = 0; i < allSockets.fd_count; i++) 120 { 121 closesocket(allSockets.fd_array[i]); 122 } 123 FD_ZERO(&allSockets); 124 WSACleanup(); 125 return 0; 126 }