Socket Select with empty fd set
Suppose you have an fd set which can have zero or more 开发者_如何学JAVAsockets in it. When I try to call select operation on empty fd set, what I get is -1 as the number of fds which are set, meaning error. So what would you suggest to overcome this problem, you might say do not call if empty but I have a loop and any time fd set can hold 0 or more sockets. What is the best approach about this problem? (we are on C programming language)
That's not right. You should be able to specify 0 as the number of file descriptors in the set. In fact, that's how I remember doing timeout code in the early days, using select
with no descriptors and a timeout value set appropriately.
If it's returning -1, you need to look at errno
to see what the problem is.
Ah, based on your comment, WSAEINVAL
means WinSock. That explains your problems. It's a hideous beast that should be put out of our misery :-)
This page here states that you will get WSAEINVAL
if the time-out value is not valid or all three descriptor parameters are null. It later states that FD_ZERO
"initialises the set to the null set". Whether that last snippet means that the parameter is still considered NULL, I don't know. Assuming that your timeout is okay (since it works if you have an FD in one of the sets), that's probably the case.
I do know that Berkeley sockets distinguishes between a NULL FD set (i.e., a NULL pointer) and and empty FD set (a valid pointer with no FDs set) - WinSock may not be that versatile especially since the nfds
is ignored and included only for compatibility with Berkeley.
I suspect (although I'm not sure) that WinSock is probably expecting you to not do what you're trying to do. It may well just assume that you're doing something wrong and should use select
only for one or more sockets in one or more FD sets (since the only use for select
with no FDs is a delay and Windows has plenty of better ways of doing delays).
Under Windows, the select
function ignores the nfds
argument entirely.
I can't test this currently, but it's possible that an error is returned if all sets are non-NULL but empty.
To work around this, you can either skip the select entirely, or keep a dummy socket to ensure that there is at least one socket in the set at all times.
Please read the select help. It says WSAEINVAL will be returned if "The time-out value is not valid, or all three descriptor parameters were null." . It's obvious you are passing an incorrect timeout value also. So, provide a correct timout value if you want to use with 0 descriptors.
精彩评论