0

I haven't found sample code demonstrating this. Below is part of the code that I tested on a set of sockets. Note that (not in the below code), I set "except_set" to be the union of "read_set" and "write_set" in order to monitor all sockets involved.

Basically what I expect to see is when error happens, it should print out the list of error-some socket(s). However, what I observe is the case of "n == -1" which only gives one error message (in my case, "bad file descriptor"). It would be better to print out the socket which encounters the error.

Another issue: Since there is only one "errno" how can it represent error for multiple sockets (if more than one sockets encounter error in one select() call). I am really confused. What kind of error(s) would "except_set" capture on per socket basis? What is proper way of using it? Thanks a lot.

    int n = select(max_fd + 1, &(read_set), &(write_set), &(except_set), &tv);

    if (n == -1)
    {
        perror("select()");
        exit(1);
    }

    else if (n == 0)
    {
        // process time-out ...
    }

    else // (n > 0)
    {
        for (int i=0; i < max_fd; ++i)
        {
            if (FD_ISSET(i, &(read_set)))
            {
                // process read
            }

            if (FD_ISSET(i, &(write_set)))
            {
                // process write
            }

            if (FD_ISSET(i, &(except_set)))
            {
                printf("error, %s, socket= %d", strerror(errno), i);
            }
        }
    }
4

1 回答 1

2

The value of errno you're checking has nothing to do with the socket which has an exceptional condition. In fact it has nothing to do with select. It's just leftover from some previous call, or set spuriously during a non-error condition. The only time errno is meaningful is immediately after receiving a failure return value (usually -1 or NULL) from a standard library function.

As for what exceptional conditions means:

If a socket has a pending error, it shall be considered to have an exceptional condition pending. Otherwise, what constitutes an exceptional condition is file type-specific. For a file descriptor for use with a socket, it is protocol-specific except as noted below. For other file types it is implementation-defined. If the operation is meaningless for a particular file type, pselect() or select() shall indicate that the descriptor is ready for read or write operations, and shall indicate that the descriptor has no exceptional condition pending.

...

A socket shall be considered to have an exceptional condition pending if a receive operation with O_NONBLOCK clear for the open file description and with the MSG_OOB flag set would return out-of-band data without blocking. (It is protocol-specific whether the MSG_OOB flag would be used to read out-of-band data.) A socket shall also be considered to have an exceptional condition pending if an out-of-band data mark is present in the receive queue. Other circumstances under which a socket may be considered to have an exceptional condition pending are protocol-specific and implementation-defined.

Source: http://pubs.opengroup.org/onlinepubs/9699919799/functions/select.html

If the socket has error status, it can be obtained with the SO_ERROR option of getsockopt.

Normally, there is no need to use the exception set with select. If the socket has been closed, it will show up as readable and will give you end-of-file (a zero-length read). Often however loss of connection will not be immediately detected by the protocol stack anyway, and so you'll just get a write error (and possibly SIGPIPE unless you suppress it) attempting to write to the socket, at which time the system determines it can no longer write. Personally I've never found occasion to use the exceptional set with select.

于 2013-04-27T01:35:27.337 回答