简体   繁体   English

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

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

According to this page : 根据这个页面

The select function returns the total number of socket handles that are ready and contained in the fd_set structures. select函数返回已准备好并包含在fd_set结构中的套接字句柄总数。

Is it thereotically possible that the return value is greater than 1 if I add only one (and the same) SOCKET to each of the FD_SET s and pass them to select ? 如果我只向每个FD_SET添加一个(和相同的) SOCKET并将它们传递给select ,那么返回值是否有可能大于1? It would mean that I must handle multiple events on the same socket. 这意味着我必须在同一个套接字上处理多个事件。 Example: 例:

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? */

One more question: Is it possible to occur that I must handle an exception and also a non-exception event on the same socket at the same time? 还有一个问题:是否有可能发生我必须同时在同一个套接字上处理异常和非异常事件?

Is it thereotically possible that the return value is greater than 1 if I add only one (and the same) SOCKET to each of the FD_SET s and pass them to select ? 如果我只向每个FD_SET添加一个(和相同的) SOCKET并将它们传递给select ,那么返回值是否有可能大于1? It would mean that I must handle multiple events on the same socket. 这意味着我必须在同一个套接字上处理多个事件。

Regardless of whether select() does or does not count the same SOCKET multiple times in the return value (that is very easy to test), you should be ignoring the actual number. 无论select()在返回值中是否多次计算相同的SOCKET (这很容易测试),您应该忽略实际的数字。 A return value that is > 0 simply tells you that ANY of the fd_set s contain sockets that match the requested events ( select() modifies the fd_set s to remove sockets that do not match). 大于0的返回值只是告诉您任何fd_set包含与请求的事件匹配的套接字( select()修改fd_set以删除不匹配的套接字)。 Even if you knew the total number of sockets, you still have to check the individual sockets with FD_ISSET() , so the actual number when the return value is > 0 is not very meaningful in real world processing. 即使您知道套接字的总数,您仍然必须使用FD_ISSET()检查各个套接字,因此返回值> 0时的实际数字在实际处理中没有多大意义。 Only -1 (error), 0 (timeout) and > 0 (events present) are meaningful. 只有-1(错误),0(超时)和> 0(存在的事件)才有意义。

And yes, a socket can have multiple events enabled at the same time. 是的,套接字可以同时启用多个事件。 For instance, a socket can be both readable and writable at the same time. 例如,套接字可以同时是可读写的。

For example: 例如:

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

Is it possible to occur that I must handle an exception and also a non-exception event on the same socket at the same time? 是否有可能发生我必须同时处理异常以及同一套接字上的非异常事件?

It depends on the nature of the exception. 这取决于例外的性质。 Not all exceptions are fatal errors. 并非所有例外都是致命错误。

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

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