   [Sockets in C++] select() lies to me?
  I'm having some trouble checking a socket for availabilityI made a small program that pumps data from socket A to B and vice versa.The problem is that both directions are processed by two different independant objects, buffering the data to create some artificial delays and other "effects". This creates the following requirements:When a Socket shuts down (by error, not by close()), one part of the program should be able to detect that it is down without actually reading of writing to it. (this would disturb the other objects working with the sockets)Since this program should work as a transparant tcp-tunnel, faillure to do so would result in a program on one end of the "tunnel" still keeping a connection while the other side is already closed down its side. This won't be detected until it actually tries to send something over. I tried the select() function, which should tell me if a write operation is GUARANTEED to succed (meaning that it is at least still a valid socket. But it will gladly say so, even if the program connected to the socket has stopped running minutes ago.Here a part of the code that checks the status of a socket:...FD_ZERO(&set);FD_SET(mysocket, &set);result = select(0, 0,&set,0, &v);if (result == 0) {return false;}if (result == 1) {return true;}//throw some exceptionThis will continue to return true, even though mysocket is down. If I then actually try to write, it of course returns with an error.Am I reading the documentation wrong, or is there something else going on?Thanks in advance   
  You must to assigned for errors and process it.FD_ZERO(&set);FD_SET(mysocket, &set);FD_SET(mysocket, &err;result = select(0, 0,&set,&err, &v);   if (FD_ISSET(mysocket, &err))   {   if (errno != 9)Disconnect(mysocket); };  Yes you're right. Forgot to mention that I first check for those too:fd_set set;FD_ZERO(&set);FD_SET(ws, &set);TIMEVAL v; //no timeout, direct feedbackv.tv_usec = 0;v.tv_sec = 0;unsigned int result = select(0, 0,0, &set, &v);if (result == 1) throw SocketError(...);if (result > 1) throw SocketError(...);..code from first post goes hereDidn't know select actually changes the set structure to include only the "passing" sockets.In your code, what is 9 in your errno check?   ;Quote:Original post by jaapI tried the select() function, which should tell me if a write operation is GUARANTEED to succed (meaning that it is at least still a valid socket. But it will gladly say so, even if the program connected to the socket has stopped running minutes ago.Here a part of the code that checks the status of a socket:...FD_ZERO(&set);FD_SET(mysocket, &set);result = select(0, 0,&set,0, &v);if (result == 0) {return false;}if (result == 1) {return true;}//throw some exceptionThis will continue to return true, even though mysocket is down. If I then actually try to write, it of course returns with an error.Am I reading the documentation wrong, or is there something else going on?You are reading the documentation wrong. select() doesn't return a value that tells you about the state of the sockets. It modifies the socket sets to tell you which ones are available for writing, or reading, or have exceptions, and returns how many are 'available'. It doesn't even say a write will succeed, only that the socket is ready for it. Generally speaking it's not always practical to know that socket is disconnected until you attempt to write to it. If a remote system had a power cut 3 milliseconds ago, how is your computer supposed to know? Always assume your writes can fail. Select just tells you that you're not going to be wasting time waiting for them to start.Generally, you should pass your sockets in as part of both the write and the exception sets, call select, and check for the exception and write-ready states with FD_ISSET.   ;  I agree with you. The problem is as follows.I have two clients communicating with each other, and my program is in the middle, relaying all data (albeit buffered and sometimes altered) back and forth. The thing is that my program is supposed to be completely transparent to the two programs.So when one of the program closes the connection on their side, this must be detected (without actually reading or writing by that part of the program) and the program must drop the connection "at the other side" so the transparency is preserved.Of course it can be solved by creating extra commication dataflow in my program, but this would very much clutter the design.   ;Quote:Original post by jaapSo when one of the program closes the connection on their side, this must be detected (without actually reading or writing by that part of the program) and the program must drop the connection "at the other side" so the transparency is preserved.Unfortunately this is impossible. If they've fallen off the internet entirely (eg. power cut), then you're not necessarily going to know about it in a timely fashion. How would you distinguish 'connection broken' from 'no data to send'? If you're lucky, the physical layer will detect a problem and propagate it up as an exception. More likely, it'll wait until you try and use it. You have no practical alternative than to check to see if your reads and writes fail.   ;  Yeah I had the same thing in mind. One thing kinda bugs me thoughA failed reading I can understand, since this will detect problems on the TCP layer, the other peer can't be reached for any acknowledgement of reception.But how come that a read operation also detects a broken connection. What else does reading do, except for passing the contents of the data buffer? Does it also actively send data over the network?   ;  A receive will not immediately detect a failed connection. However, once it's determined that the connection is failed, that can be communicated through the receive call.Ways of detecting failed connections include time-outs waiting for acknowledgement, or some remote NAT sending a RST (reset) when it can't get to the other end, or some remote router sending destination port unreachable ICMP (if that's wired up to the TCP layer).;  Said already above, but I thought I'd clarify;Select() says a socket is ready for writing, reading, or exceptions on a number of occasions. One of these occasions is CloseSocket(). Another after Accept(), when it is ready to read or write, and there are a handful of others.Basically Select() is not for checking to see if a socket is ready to write or read only.So it's not lying to you, it's just giving you more information than you expected. I wouldn't recommend using Select() soley to handle disconnects from clients. I would personally send a disconnect message to be ackonwledged by the server and then updated throughout the clients, then remove that closed socket from the masterset and continue.- Mike   ;  select() for read tells you whether you can call recv() without blocking. That's all. There are a number of reasons why recv() would not block. One is that at least one byte of data is available. Another is that the remote client disconnected, and recv() will return 0.Same thing for writing: select() for write tells you whether you can call send() without blocking. That's all. This means that there's at least one byte of output buffering space available.