Winsock2 select():同一个套接字上可能有多个事件吗?

Winsock2 select(): multiple events on the same socket is possible?

本文关键字:可能有 事件 套接字 select 同一个 Winsock2      更新时间:2023-10-16

根据此页面:

select 函数返回套接字句柄的总数,该 已准备就绪并包含在fd_set结构中。

如果我只向每个FD_SET添加一个(和相同的(SOCKET并将它们传递给select,返回值是否有可能大于 1?这意味着我必须处理同一套接字上的多个事件。例:

SOCKET someRandomSocket;
FD_SET readfds;
FD_SET writefds;
FD_SET exceptfds;
timeval timeout;
/* ...
Connecting someRandomSocket to another peer.
... */
FD_ZERO(&readfds);
FD_ZERO(&writefds);
FD_ZERO(&exceptfds);
FD_SET(someRandomSocket, &readfds);
FD_SET(someRandomSocket, &writefds);
FD_SET(someRandomSocket, &exceptfds);
int total = select(0, &readfds, &writefds, &exceptfds, &timeout);
/* total > 1 is possible? */
/* (FD_ISSET(someRandomSocket, &exceptfds) && (FD_ISSET(someRandomSocket, &readfds) || FD_ISSET(someRandomSocket, &writefds)) == true) possible? */

还有一个问题:是否有可能我必须同时处理同一套接字上的异常和非异常事件?

如果我

只向每个FD_SET添加一个(和相同的(SOCKET并将它们传递给select,返回值是否可能大于 1?这意味着我必须处理同一套接字上的多个事件。

无论select()是否在返回值中多次计算相同的SOCKET(这很容易测试(,都应该忽略实际数字。> 0 的返回值只是告诉您任何fd_set都包含与请求的事件匹配的套接字(select()修改fd_set以删除不匹配的套接字(。 即使你知道套接字的总数,你仍然需要用FD_ISSET()来检查各个套接字,所以当返回值>0时的实际数量在现实世界的处理中不是很有意义。 只有 -1(错误(、0(超时(和> 0(存在事件(有意义。

是的,一个套接字可以同时启用多个事件。 例如,套接字可以同时是可读和可写的。

例如:

FD_SET readfds;
FD_SET writefds;
FD_SET exceptfds;
FD_ZERO(&readfds);
FD_ZERO(&writefds);
FD_ZERO(&exceptfds);
FD_SET(someRandomSocket, &readfds);
FD_SET(someRandomSocket, &writefds);
FD_SET(someRandomSocket, &exceptfds);
timeval timeout;
timeout.tv_sec = ...;
timeout.tv_usec = ...;
int total = select(0, &readfds, &writefds, &exceptfds, &timeout);
if (total == -1)
{
// error in select() itself, handle as needed...
}
else if (total == 0)
{
// timeout, handle as needed...
}
else
{
if (FD_ISSET(someRandomSocket, &exceptfds) )
{
// socket has inbound OOB data, or non-blocking connect() has failed, or some other socket error, handle as needed...
}
if (FD_ISSET(someRandomSocket, &readfds) )
{
// socket has inbound data, or has disconnected gracefully, handle as needed...
}
if (FD_ISSET(someRandomSocket, &writefds) )
{
// socket is writable, or non-blocking connect() has succeeded, handle as needed...
}
}

是否有可能我必须同时处理同一套接字上的异常和非异常事件?

这取决于例外的性质。 并非所有异常都是致命错误。