简体   繁体   中英

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.

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 ? 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 ? 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. 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). 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. Only -1 (error), 0 (timeout) and > 0 (events present) are meaningful.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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