Sha*_*Lee 6 sockets objectinputstream
此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)
Run Code Online (Sandbox Code Playgroud)
从有关setSoTimeout方法的JAVA API文档中,如果此方法设置为非零值,则当时间到期时,仅引发SocketTimeoutException,而不引发SocketException:Connection超时,因此,此异常不应与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.
Run Code Online (Sandbox Code Playgroud)
但是,由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();
Run Code Online (Sandbox Code Playgroud)
java.net.SocketException:连接超时异常与setTimeout方法无关,而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
Run Code Online (Sandbox Code Playgroud)
虽然此日志引发java.net.SocketException:连接在调用的writeObject约15分钟后在22:54超时。
因此,我们可以得出结论,此异常是由以下原因引起的:tcp连接可能由于长时间(约30分钟)没有流量而无法使用,同时没有调用socket.close()方法来关闭实例套接字,然后抛出此异常。
因此,为避免此异常,应使用Socket.setKeepAlive()方法使连接保持活动状态,尽管可能未使用setTimeout()方法,这意味着要求套接字无限量地接收;
或在您的应用程序中应用心跳机制。
| 归档时间: |
|
| 查看次数: |
30919 次 |
| 最近记录: |