Java Socket class is lying regarding connection status
We have a Java client that keeps a persistent socket connection open to a remote server. The client polls a DB table every 15 seconds and if there a new item, it serializes and writes it to the socket.
Before writing to the output stream, I would like to check whether socket connection is still good. For the specific application logic doing this proactive check is simpler than catching an exception and reconnecting reactively.
I used following code figure out which method can let me know when the connection is broken:
LOG.debug("Socket status: bound=" + _socket.isBound() + ", closed=" + _socket.isClosed() + ", connected=" + _socket.isConnected() + ", outputShutdown=" + _socket.isOutputShutdown() + ", inputShutdown=" + _socket.isOutputShutdown());
I briefly disable my network adapter and during the next polling, as expected, there was an exception while writing to the socket.
However, the debug statement printed the following:
"Socket status: bound=true, closed=false, connected=true, outputShutdown=false, inputShutdown=false"
I expected either closed to be true or conn开发者_运维知识库ected to be false. What actual values I get seem to be a lie.
Is there a way to reliably check the connection status of a socket?
Read the Socket class Javadoc carefully.
isConnected is true if the socket was able to connect. The method name is a misnomer, it would more accurate if it was hasConnected.
Once the socket successfully connects it becomes true and stays true. Same thing for isBound. You have to try a socket operation and check for failure.
I'm not 100% sure about this, but I'm pretty certain that the underlying BSD Sockets API doesn't actually have a mechanism to determine whether or not a TCP stream is still open; having a read()
or write()
fail is a pretty reliable way to tell that the stream has been torn down.
Java Network Programming by Elliot Rusty Harold offers the following gem:
"...To tell if a socket is currently open, you need to check that isConnected() returns true and isClosed() returns false. For example:
boolean connected = socket.isConnected() && ! socket.isClosed();"
Hope this helps.
精彩评论