Reputation: 201
InputStream
, OutputStream
and Socket
) then how can I inform
the other end about the disconnection? There is one way I know of - trying to read from the InputStream
,
which throws an IOException
if connection is closed, but is there any other way to detect this?inputStream.available()
does not solve this problem. Why is that?Additional Information : I'm asking for another way because my project becomes tough to handle if I have to try to read from the
InputStrem
to detect a disconnection.
Upvotes: 1
Views: 12160
Reputation: 347334
Q1 If you close the socket connection on server, the client should throw an exception if not immediately, certainly on the next read attempt, and visa versa.
Q2 From the JavaDocs
Returns an estimate of the number of bytes that can be read (or skipped over) from this input stream without blocking by the next invocation of a method for this input stream. The next invocation might be the same thread or another thread. A single read or skip of this many bytes will not block, but may read or skip fewer bytes.
This is not an indication of the number of bytes currently in the stream, but an estimate of the number of bytes that may be read from the implementation that won't block the current thread
Upvotes: 0
Reputation: 311050
trying to read from the InputStream, which throws an IOException
That is not correct. If the peer closes the socket:
read()
returns -1readLine()
returns nullreadXXX()
throws EOFException
, for any other X.As InputStream
only has read()
methods, it only returns -1: it doesn't throw an IOException
at EOS.
Contrary to other answers here, there is no TCP API or Socket method that will tell you whether the peer has closed the connection. You have to try a read or a write.
You should use a read timeout.
InputStream.available()
doesn't solve the problem because it doesn't return an EOS indication of any kind. There are few correct uses of it, and this isn't one of them.
Upvotes: 7
Reputation: 13137
The problem is not "if the server/client closes the connection". The problem is "what if they do not close the connection and yet the connection is broken?"
There is no way to detect that without a heartbeat protocol of your own.
Another option is to set SO_KEEPALIVE to true.
"When the keepalive option is set for a TCP socket and no data has been exchanged across the socket in either direction for 2 hours (NOTE: the actual value is implementation dependent)"
In my experience, it is much sooner than every 2 hours. More like a ~5 minutes. Other than using So_KEEPALIVE, you are royally screwed :P
In my communications protocols, I use a reserved 'heartbeat' byte that is sent every 2 seconds. My own filterInputStream and filterOutputStream sends/and digests the heartbeat byte.
Upvotes: 0
Reputation: 7234
There is no O-O-O way to get a callback/exception the moment the connection is broken. You only get to know about the broken connection only when you do a explicit read/write on the socket stream.
There are two ways to read from a socket viz. Synchronously read byte by byte as they arrive; or wait untill a desired number of bytes available on the stream and then do a bulk read. You do the check by calling available() on the socket stream which gives you the number of bytes currently available for read. In the second case, if the socket connection is broken for some reason there is no way you can be notified of that. In that case you need to employ a timeout mechanism for your wait. In the first case where you do explicit read/write you get an exception.
Upvotes: 0