tags:

views:

472

answers:

2

I have a C++ app that uses standard socket calls and I want to know if I can tell if a socket is still open without sending or receiving any data. Is there a reliable select or ioctlsocket call I can make?

+2  A: 

A socket being "open" doesn't help you with end-to-end connectivity. The only way to know for sure that you can communicate with the other end is to, well, communicate with the other end.

In any protocol you design, you should think about implementing this checking behavior. If it's not your protocol, there's sometimes ways to do it sneakily (for example FTP up a very small, useless file to check if the FTP ports are both still open).

paxdiablo
+3  A: 

If you try to recieve one byte, you can receieve several errors, if you were to have a non-blocking socket, and try to receieve on a valid connection, you will get the error WSAEWOULDBLOCK.

Knowing this we can check a non blocking socket like so

bool connected(SOCKET sock)
{
     char buf;
     int err = recv(sock, &buf, 1, MSG_PEEK);
     if(err == SOCKET_ERROR)
     {
          if(WSAGetLastError() != WSAEWOULDBLOCK)
          {return false;}
     }
     return true;
}

as you can see from the return value of recv recv may return a timeout or several other errors for disconnect, i belive WSAEWOULDBLOCK is the only value it may return if there was an error but still connected, but you may want to double check that list of return values. Also the flag used in recv (MSG_PEEK) means that the data is still read-able when you go to look later after the check, so you don't need to worry about losing one byte of data.

I believe this will only work well with non-blocking sockets, as it may block until it receives data. If you want to use blocking socket you may want to set it non-block with ioctlsocket before this check, then return it to how it was.

For blocking sockets you would use select.
Brian R. Bondy