I have one thread (thread a) in the server that is executing object = ois.readObject();. When I pull out the LAN wire from the client, this thread does not get an exception and is continuing reading from the stream.
Another thread (thread b) on the server is trying every one second to write one byte to the client in order to check if the connection is still alive: checkingStream.writeObject(b);
when I pull this wire, I get an IOException from checkingStream.writeObject(b);. I would like “thread b” to cause “thread a” to stop reading from the stream and proceed in code / throw an exception.
threadA.interrupt(); does not do work. What shall I do?
Well I would say that this is correct behaviour. The internet (in general) and IP-based networking protocols are designed to be resilient to local interruptions … like disconnection from the network.
The problem in your case is that nothing that the reading thread is doing is telling the network stack that it expects data do be delivered every second. So the network stack cannot tell whether there is an issue with the network … or the remote service … or no data for 1 second is simply normal behaviour.
The solution is either to set a read timeout as EJP recommends, or to remove your stuff aimed at detecting that the network is there all of the time. I recommend the latter. Unless you have an overriding application-specific need to know that the network is always there, it is just best to ignore any short term network interruptions, and/or design your application-level protocols to be resilient.
Read timeouts are one option. Another way to unjam the blocked
readcall is to have another thread callclose()on theSocket. That will cause any pending reads or writes on Java streams associated with the socket to terminate with an exception.About read timeouts:
What is unsafe it trying to continue using a socket after you have received a timeout exception on it. If you use timeouts, you need to throw away the connection and create a new one after a socket-level timeout.
If you don’t want to do this, then you need to implement your timeouts in a different way. For instance, create a new thread that monitors the state of the reading thread and the data that it reads. If the new thread detects no activity from the reading thread, it can raise the alarm … while leaving the reading thread blocked in the read call in case the connection springs back into life.