繁体   English   中英

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

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

根据这个页面

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...
    }
}

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM