After I open a socket, I would like to monitor the connection to see if it is still alive. Is there any way to do this short of writing to it and seeing whether this throws an exception?
While catching the exception will certainly detect a broken connection, it might be long after the server or network goes down. The problem is that the socket streams are buffered, so if there is data in the local buffer, it is possible to read from a socket even though the network is down or the server is not responding. An exception won't be thrown until you've exhausted the buffer and need to go out over the net to refill it.
The reason this is a frequently asked question is because many people have a misconception about Sockets - they don't realize that a "connection" is an abstract concept. With an electrical appliance, it's easy to tell when your power connection is broken because there should be an alternating voltage across the poles. If there isn't, there's a break in the connection somewhere between your applicance and the power company. This can be instantly detected using a lamp, for example. If the lamp goes off, the connection is broken.
But with a socket connection, there is no carrier wave. The only ways to know a connection is broken abnormally (indeed, the definitions of a broken connection), are:
- you send a packet and fail to get a reply within a "reasonable" time
- you try to read a packet and fail to receive data within a "reasonable" time
(The TCP KEEP_ALIVE feature, enabled using the setKeepAlive() method in JDK 1.3+, uses polling in the transport layer to periodically check the connection in this manner.)
Of course a Socket could also be shut down deliberately, in which case a negotiated end to the TCP session takes place and you find this out immediately (an IOException might be thrown, for instance).