I'm in the middle of porting bits of a Winsock application to Linux. Luckily when I first wrote the networking bits I had made an effort to write it in a somewhat cross platform manner. As a result, I stuck to
recv(), and all the other function calls that Winsock provides that are close to the Berkeley socket interface. Things go pretty smoothly, although for some reason there's this really weird pause when connecting that didn't exist before...
Finally I hit a point where, for some reason, I couldn't establish a connection to the server and it just times out. That's really strange, so I threw good old debug statements all over the place and find out that this
select() call is not doing much of a select:
if (select(0, &rdset, &wtset, &errset, &tv) > 0)
Notice the 0? MSDN states that it is:
Ignored. The nfds parameter is included only for compatibility with Berkeley sockets.
Then I check the equivalent docs on the Linux side of things:
nfdsis the highest-numbered file descriptor in any of the three sets, plus 1.
Well, if I set
nfds to 0,
select() won't be doing very much selecting! Windows has
FD_SETSIZE at 64 by default, and it ignores
nfds and just checks whatever descriptors are in the
fd_sets that you pass to it. Linux considers sockets and files the same thing, and thus has a much higher
FD_SETSIZE (1024 and 4096 seem to be common). You don't want
select() checking 4096 descriptors, so you set nfds to the highest file descriptor you want it to check, plus one. (As an aside, setting nfds to
FD_SETSIZE is a bad idea.)
if (select(my_socket + 1, &rdset, &wtset, &errset, &tv) > 0)
my_socket is an appropriate file descriptor (such as the one returned by
socket()). This works just fine in Windows too, since it ignores the
Armed with this newfound knowledge, I go and fix all the other
select() statements in my code, which ends up fixing the weird pause as well. Effectively, without a proper
select() just acts as a timer and blocks until the specified amount of time has elapsed.