我有以下情况:使用“经典”Java服务器(使用ServerSocket)我希望在与客户端的连接意外失败时(即非正常/没有FIN数据包)检测(尽可能快) )。
我正在模拟的方式如下:
在10k左右的数据之后发送的块会发生什么。我不知道多久,但我已经好几次等了10多分钟。到目前为止我研究的内容:
如何检测此错误情况,或者至少配置超时值? (在JVM或OS级别)
更新:在〜20min之后,checkError在PrintWriter上返回true(在CentOS机器上使用服务器JVM 1.5)。配置此超时值在哪里?
答案 0 :(得分:3)
大约20分钟的超时是因为Linux中的标准TCP设置。除非你知道自己在做什么,否则捣乱他们真的不是一个好主意。我在工作中有一个类似的项目,我们通过断开网络电缆来测试连接丢失,事情会长时间挂起,就像你看到的那样。我们尝试搞乱以下TCP设置,这使得超时更快,但是在其他应用程序中会导致副作用,因为当事情变得繁忙时,网络会因网络延迟而导致连接断开。
net.ipv4.tcp_retries2
net.ipv4.tcp_syn_retries
如果您查看tcp(man tcp)的手册页,您可以阅读这些设置的含义,并可能找到可能适用的其他设置。您可以直接在/ proc / sys / net / ipv4下设置它们,也可以使用sysctl.conf。这两个是我们发现发送/接收失败更快的那些。尝试将它们都设置为1,您将看到发送调用失败的速度要快得多。在更改之前,请确保不要使用当前设置。
我会重申你真的不应该搞乱这些设置。它们可能对操作系统和其他应用程序产生副作用。最好的解决方案就像Kitson所说,使用心跳和/或应用程序级别超时。
另请参阅如何创建非阻塞套接字,以便发送调用不会像这样阻塞。虽然请记住,只要发送缓冲区中有空间,使用非阻塞套接字发送通常是成功的。这就是为什么它在阻塞之前需要大约10k的数据,即使你在此之前断开了连接。
答案 1 :(得分:2)
唯一可靠的解决方法是生成应用程序级别的“检查”,而不是依赖于传输级别。例如,双向心跳消息,如果任一端未获得预期消息,则关闭并重置连接。