连接阶段后“java.io.IOException:连接超时”的含义

时间:2014-08-25 16:36:45

标签: java sockets nio

可能相关: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。

问题是:

  1. 此超时是否可配置?

  2. 为什么netstat输出将套接字状态显示为ESTABLISHED?理想情况下它应该是CLOSE_WAIT(当客户端断开连接时)

4 个答案:

答案 0 :(得分:2)

该超时通常是不可配置的,因为它取决于操作系统提供的可能性。 Unix 一般不允许进程修复连接超时,通常它会在两分钟左右固定到 。也许某些版本的 linux / BSD 系统允许对其进行配置,但这不是可移植的,通常不允许将其修复给用户(仅限管理员)。这与每次尝试使用的重传次数和超时有关,并且受TCP实施的独占控制。

完成连接后,您将通过两种状态( FIN_WAIT TIME_WAIT 不是超时状态。两个中的第一个是获得另一端的响应(你可以关闭你的连接一边告诉对方你不会发送更多的数据,但你必须等待另一端做同样的事情)< strong> TIME_WAIT 是内核维护的一种特殊状态,用于关闭连接以处理(并丢弃)连接关闭后当前可能的最后帧的所有可能重传。它们与超时无关。

tcp连接没有超时隐式。两台机器可以通过几周而不交换任何信息,如果它们没有任何传输。您可以控制在静默连接之间使用某种心跳以使用一个套接字选项检查其活动 SO_KEEPALIVE )此选项使两侧的tcps交换空数据包要知道对方是否还活着。同样,您只能控制此数据包的使用,不是关闭连接的丢失帧的频率或数量(这可以在linux中配置,但仅在管理员模式下触摸内核配置)

注1(回答@Krishna Chaitanya P)

如果您拔掉电缆并在一段时间后获得例外,这可能是导致这种情况发生的两个原因之一:

  1. 您继续写入该连接并且发送缓冲区已经填满而未及时得到确认(这种情况很少见,因为通常情况下您的进程会在 write(2)系统调用中被阻止)确实发生了一些超时(在套接字的java实现中)。
  2. 您的tcp套接字的java实现使用 SO_KEEPALIVE 选项(最可能的事情)。正如我之前所说,你有布尔控件可以使用或不使用它,但你不能调整keepalive之间的时间或它们丢失连接的数量。尝试在Socket类上调用 getKeepAlive() / setKeepAlive(boolean)方法来控制此功能。我没有在文档中看到,默认情况下,连接套接字是否为keepalived。到目前为止,这是服务器中常用的选项,因为它允许在不告知服务器的情况下断开丢失连接的客户端。

答案 1 :(得分:2)

  1. 不可配置。这是重新传输超时的结果。除非应用程序继续写入,否则它将不会发生,或者在断开连接时进行挂起写入。

  2. 它不应该是CLOSE_WAIT,因为没有收到FIN。它应该是ESTABLISHED。

答案 2 :(得分:0)

根据我的经验,连接套接字发生此异常的原因始终是由于防火墙关闭了空闲时间过长的连接。我已经看到它特别发生在云环境(AWS,Rackspace)中,但并不仅限于此。最有可能的是,在两个连接对等体之间有某种防火墙,一段时间后关闭空闲连接。

理想世界中的最佳解决方案是更改防火墙配置,前提是您或运营团队可以访问它。在任何情况下,最好是在代码中处理该用例并优雅地终止与其他对等方的通信。

答案 3 :(得分:-2)

因为CLOSE_WAIT状态是FI等待来自对等体的相应FIN,而不是这里的情况。

这个TO很可能是可配置的