select() seems tied to cout/stdout?
I'm using select() to figure out when a non-blocking connection either connects, is connecting, or fails to connect; using TCP sockets on Linux. My actual TCP connections connect and work properly, this is just to detect their status.
The weird thing is that my code always first gives me what I consider a CONNECTIONFAILED .. after the cout (any cout) the next call to select() gives me what I consider CONNECTED. Whether or not the socket connects doesn't matter.
I've verified that I'm using a good looking socket (it's int id is 3 in this case, and like I said it does play nice with actual connections verified by connecting to a listening netcat)
My top level code is
while(1)
{
state = networking.connectionStatus(socketId);
.. [cout would go here or not, as described above]
if(state == CONNECTED) { // connected! }
else .. // connecting, or connection failed code
}
My select code, operating on this nonblocking socket that's passed in to connectionStatus
myStateType connectionStatus(int socket)
{
struct timeval tv;
tv.tv_sec = 0; tv.tv_usec = 0; // no timeout, immediately return from select()
fd_set ourFdSet;
FD_ZERO(&ourFdSet); // zero the set
FD_SET(socket, &ourFdSet); // put our socket in to this set
// Switch to figure out if we can write to our fd yet
switch(select(socket + 1, NULL, &ourFdSet, NULL, &tv))
{
case -1: // connection failed, actual error from select()
return CONNECTIONFAILED;
break;
case 0: // no fds ready to write, still connecting?? can someone verify this is true
return CONNECTING;
break;
case 1: // now we have 1 fd ready to write, but look closer..
// Examine our socket at the socket level for errors.. if < 0 then getsockopt fail
if(getsockopt(socket, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
return CONNECTIONFAILED;
if(error == 0) return CONNECTED;
if(error == EINPROGRESS) return CONNECTIN开发者_Go百科G;
// otherwise, failure.. (a real error)
return CONNECTIONFAILED;
.. end of function ..
So what could be going on that cout plays in here? And is all this on the right track? All the man pages and internet sources seem to agree..
select()
returning -1
does not indicate the connection failed - it indicates that select()
itself encountered an error. You should return something different (or at least, put a perror("select")
in that path). The same applies to getsockopt()
failing. Adding these will assist in debugging the problem.
The rest of it looks fine - if the socket isn't writeable (select()
returning zero), then the connection attempt is still in progress. Despite your assurances to the contrary, it sure looks like you might have your file descriptors mixed up.
Absolutely bizarre, so 'len' has to be set to 'sizeof len' before passing it in (probably properly set to sizeof error, but they're the same).
I didn't realize that was something that was read by getsockopt, I thought it was a return value only? Returning what was in the error ..
Thanks for the assistance
The comment above is correct.
You set a timeout of zero on your select, so that it returns immediately. This is a successful return value, however all FD_SETs could be left clear.
When you get a 0 w/ a timeout specifed, you must check FD_ISSET on your FD_SET. If it is not set, then you know that you have simply tripped the select timeout and the socket is not ready for writing. This explains your CONNECTERROR, I'm sure that the getsockopt() in that state is not really well defined.
精彩评论