在套接字读取时获取操作超时异常

时间:2016-11-05 17:54:46

标签: java sockets networking tcp network-programming

如果我设置mSocket.setSoTimeout(1000);

  

java.net.SocketTimeoutException:读取超时

在预期的mSocket.getInputStream().read()等待一秒后。

但是,如果我mSocket.setSoTimeout(0);我得到了

  

java.net.SocketException:操作超时

在大约一分钟(我的大多数跑步中55秒)之后,等待令人费解。

我尝试在我的Mac OS El Capitan上增加sysctl tcp设置无济于事。如果这些设置被限制为大约一分钟的超时,我应该得到与以前相同的读取超时异常。什么是这个操作超时了?

编辑:可能值得一提的是,我故意使用pfctl将网络关闭,因为我在tcp上使用websockets,我希望连接不会因为超时而中断,一旦我将网络连接起来,流程就会继续试。

两个例外的堆栈跟踪是相同的,即

at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:150)
at java.net.SocketInputStream.read(SocketInputStream.java:121)
at java.net.SocketInputStream.read(SocketInputStream.java:203)
at org.jwebsocket.kit.WebSocketProtocolAbstraction.protocolToRawPacket(WebSocketProtocolAbstraction.java:220)

1 个答案:

答案 0 :(得分:0)

当应用程序调用{​​{1}}时,OS实际上可能会永远等待数据。但是,无论SO_TIMEOUT值如何,都有几种事件会中断读操作。

如果操作系统破坏了套接字后面的TCP连接,那么读操作就会中断,因为TCP连接不再存在,并且以后没有机会接收任何数据。即使对等体稍后发送数据,本地TCP栈也会丢弃它(并且可能会回答TCP-RST)。

操作系统破坏了TCP连接,因为它发送了数据并且没有收到任何ACK。所以操作系统尝试重新传输数据,然后它放弃了并且破坏了连接。