繁体   English   中英

断开连接时,Java套接字不会超时

[英]Java socket does not timeout when severing the connection

我在自动化测试中看到一些奇怪的问题。

有以下设置:服务器:Centos 6客户端1:Windows 7客户端2:Centos 6

我正在编写测试,该测试通过阻止服务器iptables上的出站连接来模拟与服务器的连接中断。 但是,套接字的行为在Windows上与Linux客户端上的套接字不同。

不过,在两种情况下,都有一行Java代码可以执行:

socket.setSoTimeout(0)

方案1(Windows):

  • ssh命令发送到服务器iptables -A OUTPUT --dport XYZ -j DROP
  • 大约60秒后,我的控制台显示java.net.SocketTimeoutException: Read timed out
  • 连接下降

场景2(Centos)

  • 发送与上述相同的命令
  • 我尝试等待多达10分钟,但控制台从未输出异常。

因此, 问题是,有没有办法使套接字的行为相同(或近似相同)?

我读到Windows实际上不使用SO_TIMEOUTSO_RCVTIMEO代替。

setSoTimeout(int timeout)

以指定的超时时间启用/禁用SO_TIMEOUT,以毫秒为单位。 通过将此选项设置为非零超时,与此套接字关联的InputStream上的read()调用将仅在此时间量内阻塞。 如果超时到期,则尽管Socket仍然有效,但将引发java.net.SocketTimeoutException。 必须先启用该选项,然后才能执行阻止操作。 超时必须大于0。 零超时被解释为无限超时

您可以设置实际的超时值吗?

阅读了David的回答后,我观察了该套接字的行为,以了解其工作原理。

如David所述,SO_TIMEOUT仅适用于将来的read()调用,不适用于已被调用的调用。

我测试的常见模式是:

  • 连接用户(套接字)
  • 交换一些数据
  • 服务器一段时间未与用户通信
  • 此时,客户端已经输入了read方法。 此时设置SO_TIMEOUT是没有用的。
  • 阻止本地端口(某些55000+端口随机)上的服务器出站流量
  • 等待SocketTimeoutException

如果我要在之前设置SO_TIMEOUT ,我的套接字将抛出mad之类的异常。 因此,我希望并且在排除网络中断情况下抛出异常时是错误的。 相反,在交通中断的情况下会抛出异常。

这可以成为Keep-Alive的问题吗? 我的套接字将其设置为true

解决方案(经验):

我测量(在Windows上)套接字关闭大约需要60秒。

因此,当我需要断开连接时,我创建了一个线程,每2秒检查一次当前时间是否大于(creation time + 60s) 当达到该时间时,它将调用socket.close ,这实际上会导致SocketException

这种解决方案绝不是最佳方案,但至少现在是必须这样做。

希望这对这里的其他人有帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM