2016-11-05 60 views
1

如果我设置mSocket.setSoTimeout(1000);我得到获得操作超时异常的套接字读取

java.net.SocketTimeoutException:读超时

mSocket.getInputStream().read()等待的二分之一,预计之后。

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

java.net.SocketException异常:操作超时

1分钟左右(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) 
+0

当您切断网络时,有没有正在进行的发送? – EJP

+0

是的,很可能因为我每秒发送1.5个信息。 – user3740387

回答

0

当应用程序调用setSoTimeout(0)然后OS实际上可能等待数据永远。但是,不管SO_TIMEOUT值如何,有几种事件会中断读取操作。

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

操作系统销毁了TCP连接,因为它发送了数据并没有收到任何ACK。因此,操作系统试图重新传输数据,并在过了一段时间后放弃并摧毁了连接。

+0

至于有几种事件可能会中断读取的第一个参数,如果打破此读取的事件仅在网络关闭后54-56秒后发生,我怀疑该数字是可配置的。任何猜测这个事件可能是什么? – user3740387

+0

对于第二点,“操作系统销毁了TCP连接,因为它发送了数据并且没有收到任何ACK。”我曾尝试使用sysctl操纵系统变量无济于事。由于其他人已经成功地获得了更大的无响应但仍然存在连接的情况,我可能会做错什么。 1分钟没有反应似乎太短的时间来打破tcp。 – user3740387