三-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 }
合集:
Win Socket套接字编程
分类:
Win Socket套接字编程
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构