Java SocketChannel doesn't detect disconnection?

aryaxt picture aryaxt · Aug 14, 2010 · Viewed 13.5k times · Source

I have a socket running, using selectors. I am trying to check to see if my socket is connected to the server or not.

Boolean connected = _channel.isConnected();

and it always returns true. I turned off Airport (internet connection) on my computer, and when i check to see if the socket is connected or not, it still returns true. Any idea why? I try to write data to the server every 3 seconds, and it still doesn't change the state of my socket to disconnected.

Answer

irreputable picture irreputable · Aug 15, 2010

Usually if you turn off OS level networking, writes to socket should throw exceptions, so you know the connection is broken.

However more generally, we cann't be sure if a packet is delivered. In java (probably C too), there is no way to check if a packet is ACK'ed.

Even if we can check TCP ACKs, it doesn't guarantee that the server received or processed the packet. It only means that the target machine received the packet and buffered it in memory. Many things can go wrong after that.

So if you really want to sure, you can't rely on transport protocol. You must have application level ACK, that is, the server application writes back an ACK message after it received and processed a message from client.

From client point of view, it writes a message to server, then tries to read ACK from server. If it gets it, it can be certain that its message is received and processed. If it fails to get ACK, well, it has no idea what has happened. Empirically, most likely TCP failed. Next possiblity is that server crashed. It's also possible that everything went OK, except the ACK couldn't reach the client.