что вызывает: java.net.SocketException: истекло время ожидания соединения, а не SocketTimeoutException - PullRequest
5 голосов
/ 18 января 2012

Это SocketException выбрасывается в метод ObjectInputStream.readObject (), что вызывает это исключение? Кроме того, значения soTimeout клиентского и серверного сокета равны 0, а значение KeepAlive равно 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)

Из документа API JAVA о методе setSoTimeout, если для этого метода установлено нулевое значение, по истечении времени генерируется только исключение SocketTimeoutException, а не SocketException: соединение истекло, поэтому это исключение не должно относиться с 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.

Однако значение, возвращаемое PlainSocketImpl (здесь SSLSocketImpl). GetTimeout () передается методом setSoTimeout (), тогда это все еще очень странный метод.

 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();

1 Ответ

5 голосов
/ 09 февраля 2012

java.net.SocketException: исключение тайм-аута соединения не связано с методом setTimeout, который связан только с SocketTimedoutException.

Из трассировок сообщений, захваченных tcpdump, как показано ниже:

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

пока эти журналы генерируют исключение java.net.SocketException: время соединения истекло в 22:54, примерно через 15 минут после вызова writeObject.

Таким образом, мы можем сделать вывод, что это исключение вызвано тем, что, возможно, tcp-соединение было недоступно из-за долгого (около 30 минут) отсутствия трафика, в то время как метод socket.close () не вызывается для закрытияв сокет в данном случае, затем выдается это исключение.

, поэтому, чтобы избежать этого исключения, вы должны поддерживать соединение активным, используя метод Socket.setKeepAlive (), хотя, возможно, вы не использовали метод setTimeout (), означая запрос сокета к неограниченному блоку для получения;

Или примените механизм сердцебиения в своих приложениях.

...