what causes : java.net.SocketException: Connection timed out, Not the SocketTimeoutException

Shawn Lee picture Shawn Lee · Jan 18, 2012 · Viewed 37.4k times · Source

This SocketException is thrown in ObjectInputStream.readObject() method, what cause this excetpion? Besides, the values of soTimeout of client and server socket are both 0, and KeepAlive value is false.

{2012-01-09 17:44:13,908} ERROR java.net.SocketException: Connection timed out
 at java.net.SocketInputStream.socketRead0(Native Method)
 at java.net.SocketInputStream.read(SocketInputStream.java:146)
 at sun.security.ssl.InputRecord.readFully(InputRecord.java:312)
 at sun.security.ssl.InputRecord.read(InputRecord.java:350)
 at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:809)
 at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:766)
 at sun.security.ssl.AppInputStream.read(AppInputStream.java:94)
 at sun.security.ssl.AppInputStream.read(AppInputStream.java:69)
 at java.io.ObjectInputStream$PeekInputStream.peek(ObjectInputStream.java:2265)
 at java.io.ObjectInputStream$BlockDataInputStream.peek(ObjectInputStream.java:2558)
 at    java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2568)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1314)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:368)

From the JAVA API document about the setSoTimeout method, if this method is set a no-zero value, when the times expires, only the SocketTimeoutException was thrown, not the SocketException:Connection timed out, so, this exception should not relate with the setSotimeoutMethod.

public void setSoTimeout(int timeout)  throws SocketException
 Enable/disable SO_TIMEOUT with the specified timeout, in milliseconds. With this 
 option set to a non-zero timeout, a read() call on the InputStream associated with 
 this Socket will block for only this amount of time. If the timeout expires, a 
 java.net.SocketTimeoutException is raised, though the Socket is still valid. The 
option must be enabled prior to entering the blocking operation to have effect. The 
timeout must be > 0. A timeout of zero is interpreted as an infinite timeout.

However, the value returned by PlainSocketImpl(here,is SSLSocketImpl).getTimeout() is transfered by the setSoTimeout() method, then it is still a very strange method.

 SocketInputStream.socketRead0(FileDescriptor fd, byte b[], int off, int len, int timeout)  
  the timeout value is passed in the constructor of  SocketInputStream:SocketInputStream(PlainSocketImpl impl) throws IOException {}
  timeout = impl.getTimeout();

Answer

Shawn Lee picture Shawn Lee · Feb 9, 2012

java.net.SocketException: the Connection timed out exception is not related with setTimeout method, which only is related with the SocketTimedoutException.

From the messages traces captured by tcpdump, like below:

NO.            Time       Source Destination Protocol Info
14845 2012-02-07 22:37:46 10.*   10.*        DNP 3. len=1,from 52156 to 29466,ACK 
14846 2012-02-07 22:37:46 21.*   10.*        DNP 3. len=1,from 54562 to 50276,ACK
14848 2012-02-07 22:37:46 32.*   10.*        DNP 3. [TCP Restransmission] len=1,from from 52156 to 29466,ACK 
……(7 times retransmission) 
14849 2012-02-07 22:37:47 10.*   10.*        DNP 3. [TCP Restransmission] len=1,from from 52156 to 29466,ACK

while this logs throw the java.net.SocketException: Connection timed out at 22:54, about 15minutes later from the writeObject invoked.

So we can conclude that this Exception is caused by that possibly the tcp connection has been not usable because of a long time(about 30minutes) no traffic, meanwhile there is no socket.close() method invoked to close the socket at instance, then this exception was thrown.

so to avoid this exception, you should keep the connection be alive using the method Socket.setKeepAlive() method although possibly you have not used the method setTimeout(), meaning asking the socket to unlimited block to receive;

Or apply the heart-beat mechanism in your applications.