winsock select() 返回值

The select function determines the status of one or more sockets, waiting if necessary, to perform synchronous I/O.

Syntax

int select(
  __in     int nfds,
  __inout  fd_set *readfds,
  __inout  fd_set *writefds,
  __inout  fd_set *exceptfds,
  __in     const struct timeval *timeout
);

Parameters

nfds [in]

Ignored. The nfds parameter is included only for compatibility with Berkeley sockets.

readfds [in, out]

An optional pointer to a set of sockets to be checked for readability.

writefds [in, out]

An optional pointer to a set of sockets to be checked for writability.

exceptfds [in, out]

An optional pointer to a set of sockets to be checked for errors.

timeout [in]

The maximum time for select to wait, provided in the form of a TIMEVAL structure. Set the timeout parameter to null for blocking operations.

Return value

The select function returns the total number of socket handles that are ready and contained in the fd_set structures, zero if the time limit expired, or SOCKET_ERROR if an error occurred. If the return value is SOCKET_ERROR, WSAGetLastError can be used to retrieve a specific error code.


1.如果超时返回 0

2.返回fd_set 中准备好的socket个数(不包括零)

3.如果没有准备好的返回 -1


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是一个使用winsock库的select函数的示例代码: ```c++ #include <winsock2.h> #include <stdio.h> #pragma comment(lib,"ws2_32.lib") //链接ws2_32.lib库文件 int main() { WSADATA wsaData; int iRet = 0; iRet = WSAStartup(MAKEWORD(2,2), &wsaData); //初始化winsock库 if(iRet != NO_ERROR) { printf("WSAStartup() failed with error: %d\n", iRet); return 1; } SOCKET sockServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //创建TCP socket if(sockServer == INVALID_SOCKET) { printf("socket() failed with error: %ld\n", WSAGetLastError()); WSACleanup(); return 1; } sockaddr_in addrSrv; addrSrv.sin_family = AF_INET; addrSrv.sin_port = htons(8888); addrSrv.sin_addr.s_addr = htonl(INADDR_ANY); iRet = bind(sockServer, (const sockaddr *)&addrSrv, sizeof(addrSrv)); //绑定socket到指定IP和端口号 if(iRet == SOCKET_ERROR) { printf("bind() failed with error: %ld\n", WSAGetLastError()); closesocket(sockServer); WSACleanup(); return 1; } iRet = listen(sockServer, 5); //开始监听 if(iRet == SOCKET_ERROR) { printf("listen() failed with error: %ld\n", WSAGetLastError()); closesocket(sockServer); WSACleanup(); return 1; } fd_set fdRead; //定义读文件描述符集合 FD_ZERO(&fdRead); //清空读文件描述符集合 FD_SET(sockServer, &fdRead); //将监听socket加入读文件描述符集合 while(true) { fd_set fdReadBackup = fdRead; //备份读文件描述符集合,因为select会改变集合内容 iRet = select(0, &fdReadBackup, NULL, NULL, NULL); //等待读文件描述符集合有数据可读 if(iRet == SOCKET_ERROR) { printf("select() failed with error: %ld\n", WSAGetLastError()); break; } else if(iRet > 0) { if(FD_ISSET(sockServer, &fdReadBackup)) //监听socket有数据可读,表示有新连接请求 { sockaddr_in addrClient; int addrClientLen = sizeof(addrClient); SOCKET sockConn = accept(sockServer, (sockaddr *)&addrClient, &addrClientLen); //接受连接请求 if(sockConn == INVALID_SOCKET) { printf("accept() failed with error: %ld\n", WSAGetLastError()); break; } printf("New client connected: %s:%d\n", inet_ntoa(addrClient.sin_addr), ntohs(addrClient.sin_port)); FD_SET(sockConn, &fdRead); //将连接socket加入读文件描述符集合 } else //连接socket有数据可读,表示客户端发送了数据 { for(int i = 0; i < fdReadBackup.fd_count; i++) //遍历读文件描述符集合中的所有连接socket { SOCKET sockConn = fdReadBackup.fd_array[i]; if(sockConn != sockServer) //排除监听socket { char szBuf[1024] = {0}; iRet = recv(sockConn, szBuf, sizeof(szBuf), 0); //接收数据 if(iRet == SOCKET_ERROR) { printf("recv() failed with error: %ld\n", WSAGetLastError()); break; } else if(iRet == 0) //对方关闭连接 { printf("Client disconnected.\n"); closesocket(sockConn); FD_CLR(sockConn, &fdRead); //从读文件描述符集合中移除连接socket } else //正常接收到数据 { printf("Received data from client: %s\n", szBuf); send(sockConn, szBuf, iRet, 0); //回复相同的数据 } } } } } } closesocket(sockServer); WSACleanup(); return 0; } ``` 该代码实现了一个简单的TCP服务器,通过select函数实现了多路复用,可以同时处理多个客户端连接。在主循环中,使用select函数等待读文件描述符集合中的socket有数据可读,当有新连接请求时,将连接socket加入读文件描述符集合,当连接socket有数据可读时,接收数据并回复相同的数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老猿的春天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值