可能相关:Difference between Connection timed out and Read timed out
我使用nio编写了一个java服务器应用程序。
我将客户端连接到我的服务器应用程序并拔下客户端的网络电缆。在服务器端,我没有立即得到任何异常但是在一段时间后(大约8分钟),我得到了“IOException:Connection timed out”
这是部分堆栈跟踪:
java.io.IOException: Connection timed out
at sun.nio.ch.FileDispatcherImpl.read0(Native Method)
at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39)
at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:225)
at sun.nio.ch.IOUtil.read(IOUtil.java:198)
at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:375)
........
直到这次,当我看到netstat输出时,我看到这个特定客户端连接的套接字状态显示为ESTABLISHED。
问题是:
此超时是否可配置?
为什么netstat输出将套接字状态显示为ESTABLISHED?理想情况下它应该是CLOSE_WAIT(当客户端断开连接时)
答案 0 :(得分:2)
该超时通常是不可配置的,因为它取决于操作系统提供的可能性。 Unix 一般不允许进程修复连接超时,通常它会在两分钟左右固定到 。也许某些版本的 linux / BSD 系统允许对其进行配置,但这不是可移植的,通常不允许将其修复给用户(仅限管理员)。这与每次尝试使用的重传次数和超时有关,并且受TCP实施的独占控制。
完成连接后,您将通过两种状态( FIN_WAIT 和 TIME_WAIT )不是超时状态。两个中的第一个是获得另一端的响应(你可以关闭你的连接一边告诉对方你不会发送更多的数据,但你必须等待另一端做同样的事情)< strong> TIME_WAIT 是内核维护的一种特殊状态,用于关闭连接以处理(并丢弃)连接关闭后当前可能的最后帧的所有可能重传。它们与超时无关。
tcp连接没有超时隐式。两台机器可以通过几周而不交换任何信息,如果它们没有任何传输。您可以控制在静默连接之间使用某种心跳以使用一个套接字选项检查其活动 ( SO_KEEPALIVE )此选项使两侧的tcps交换空数据包要知道对方是否还活着。同样,您只能控制此数据包的使用,不是关闭连接的丢失帧的频率或数量(这可以在linux中配置,但仅在管理员模式下触摸内核配置)
如果您拔掉电缆并在一段时间后获得例外,这可能是导致这种情况发生的两个原因之一:
答案 1 :(得分:2)
不可配置。这是重新传输超时的结果。除非应用程序继续写入,否则它将不会发生,或者在断开连接时进行挂起写入。
它不应该是CLOSE_WAIT,因为没有收到FIN。它应该是ESTABLISHED。
答案 2 :(得分:0)
根据我的经验,连接套接字发生此异常的原因始终是由于防火墙关闭了空闲时间过长的连接。我已经看到它特别发生在云环境(AWS,Rackspace)中,但并不仅限于此。最有可能的是,在两个连接对等体之间有某种防火墙,一段时间后关闭空闲连接。
理想世界中的最佳解决方案是更改防火墙配置,前提是您或运营团队可以访问它。在任何情况下,最好是在代码中处理该用例并优雅地终止与其他对等方的通信。
答案 3 :(得分:-2)
因为CLOSE_WAIT状态是FI等待来自对等体的相应FIN,而不是这里的情况。
这个TO很可能是可配置的