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

断开连接时,Java套接字不会超时,java,linux,sockets,timeout,xmpp,Java,Linux,Sockets,Timeout,Xmpp,我在自动化测试中发现了一些奇怪的问题 有以下设置: 服务器:Centos 6 客户1:Windows7 客户2:Centos 6 我正在编写一个测试,通过阻塞服务器的iptables上的出站连接来模拟对服务器的连接中断。但是,套接字在Windows上的行为不同于Linux客户端上的行为 但有一点是,在这两种情况下,都有一行Java代码: socket.setSoTimeout(0) 场景1(窗口): 将ssh命令发送到服务器iptables-A输出--dport XYZ-j DROP 大约6

我在自动化测试中发现了一些奇怪的问题

有以下设置: 服务器:Centos 6 客户1:Windows7 客户2:Centos 6

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

但有一点是,在这两种情况下,都有一行Java代码:

socket.setSoTimeout(0)
场景1(窗口):
  • ssh
    命令发送到服务器
    iptables-A输出--dport XYZ-j DROP
  • 大约60秒后,我的控制台显示
    java.net.SocketTimeoutException:Read timed out
  • 连接中断
场景2(Centos)
  • 发送与上面相同的命令
  • 我尝试了长达10分钟的等待,但console从未输出异常
所以,问题是,有没有办法使套接字的行为相同(或大致相同)

我读到
Windows
实际上没有使用
SO\u TIMEOUT
,而是使用
SO\u RCVTIMEO

来自:

使用指定的超时启用/禁用SO_超时,以毫秒为单位。将此选项设置为非零超时时,对与此套接字关联的InputStream的read()调用将仅阻塞此时间量。如果超时过期,则会引发java.net.SocketTimeoutException,尽管套接字仍然有效。在进入阻塞操作之前,必须启用该选项才能生效。超时必须大于0零超时被解释为无限超时


你能设置一个实际的超时值吗?

在阅读了David的答案后,我观察了该套接字的行为,以了解它是如何工作的

正如David所说,SO_TIMEOUT只适用于将来的
read()
调用,而不适用于已经调用的调用

我测试的常见模式是:

  • 连接用户(套接字)
  • 交换一些数据
  • 服务器在一段时间内不与用户通信
  • 此时,客户端已经输入了
    read
    方法。此时设置
    以便\u TIMEOUT
    是无用的
  • 在本地端口上阻止服务器的出站流量(一些随机55000+端口)
  • 等待
    SocketTimeoutException
如果我在
之前设置
超时
,我的套接字会疯狂地抛出异常。所以,我希望在网络中断的情况下抛出异常,这是错误的。相反,在通信量中断的情况下抛出异常

这是否是
保持活动状态的问题?我的套接字将其设置为
true

解决方案(经验): 我(在Windows上)测量到插座下降大约需要60秒

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

这一解决方案绝不是最优的,但至少目前是如此


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

我可能是,但对我来说奇怪的是,
Windows
不支持无限超时。我有点担心,通过更改超时,不会破坏数百个使用此连接类的现有测试。另外,请检查在进入阻止操作之前必须启用该选项才能生效。谢谢,这是一条至关重要的信息。在观察行为后,我能够以不同的方式解决这个问题。。。现在添加答案…不客气。我很高兴我的答案被接受:)