我看到自动化测试存在一些奇怪的问题。
有以下设置: 服务器:Centos 6 Client1:Windows 7 Client2:Centos 6
我通过阻止服务器iptables
上的出站连接来编写模拟连接中断到服务器的测试。但是,socket的行为在Windows上与Linux客户端上的行为不同。
但有一点,在这两种情况下都有一行Java代码:
socket.setSoTimeout(0)
ssh
命令发送到服务器iptables -A OUTPUT --dport XYZ -j DROP
java.net.SocketTimeoutException: Read timed out
那么,问题,是否有办法使套接字的行为相同(或大致相同)?
我读到Windows
实际上不使用SO_TIMEOUT
而是使用SO_RCVTIMEO
。
答案 0 :(得分:1)
使用指定的超时启用/禁用SO_TIMEOUT,以毫秒为单位。如果将此选项设置为非零超时,则与此Socket关联的InputStream上的read()调用将仅阻止这段时间。如果超时到期,则引发java.net.SocketTimeoutException,尽管Socket仍然有效。必须在进入阻止操作之前启用该选项才能生效。超时必须> 0. 超时为零被解释为无限超时。
您是否可以设置实际的超时值?
答案 1 :(得分:0)
在阅读David的回答后,我观察了该套接字的行为,以了解它是如何工作的。
正如David所说,SO_TIMEOUT仅适用于未来的read()
次呼叫,而不适用于已经呼叫的呼叫。
我测试的常见模式是:
read
方法。此时设置SO_TIMEOUT
是没用的。SocketTimeoutException
如果我要在之前设置SO_TIMEOUT
,我的套接字会抛出疯狂的异常。所以,我希望并且在网络中断的情况下抛出异常时会出错。相反,如果流量中断,则会抛出异常。
这可能是Keep-Alive
的问题吗?我的套接字将其设置为true
。
我测量(在Windows上)套接字关闭需要大约60秒。
因此,当我需要切断连接时,我会创建一个线程,如果当前时间距(creation time + 60s)
更大,则每2秒检查一次。当它到达那个时间时,它会调用socket.close
,这会有效地导致SocketException
。
这个解决方案绝不是最佳解决方案,但必须这样做,至少目前是这样。
希望这对其他人有任何帮助..