【问题标题】:testing Socket#connect timeout in java在java中测试Socket#connect超时
【发布时间】:2011-12-03 11:37:17
【问题描述】:

我最近正在调查一个 java 应用程序的操作问题。有两个进程,processA 和 processB,在同一台主机上运行。

processA 与 processB 建立套接字连接。 processB 重新启动,但不知何故,在重新启动后,来自 processA 的所有 Socket#connect 调用都被阻塞(几分钟)。

我认为 processB 的套接字处于损坏状态(接收 SYN 但从未响应)。问题自行解决(自动重启),因此我无法确定捕获 tcp 流量。

我知道我们的套接字客户端在连接时应该有一个短暂的超时(在这种情况下,操作系统默认值似乎很大)。

我只是好奇如何为我的套接字客户端编写一个失败的测试。

是否可以这样做:

@Test
public void testClientTimeoutOnConnectionAttempt() {
    startBrokenSocketServer()
    assertConnectionExceptionWithinOneSecond(myClient);
}

我想出了如何使用 ipfw 和 netcat 手动创建这些条件。

 sudo ipfw add 100 drop ip from 127.0.0.1 6969 to any
 nc -l -p 6969

nc 在 6969 上监听,(阻止 os 发送 rst,ack),并且 ipfw 阻止了我的 java 进程从 nc 接收任何 syn_ack。

在 Socket#connect 调用中没有任何超时,它在 SocketException 之前需要 75 秒(在 mac os 上)。如果我指定超时,它会更早地失败。

我需要修改的客户端属于另一个团队。我想向他们发送一个修复程序以及一个演示它的自动化测试。关于如何做到这一点的任何想法?

【问题讨论】:

    标签: java sockets testing


    【解决方案1】:

    我只是好奇如何为我的套接字客户端编写一个失败的测试。

    我认为这在 Java 中是不可能的。您当然可以模拟很多 netcat 的功能,但不能模拟 ipfw。我什至不确定这在 C 中是否可行,除非您执行一些非常特定于操作系统的内核调用。

    我认为你可以从 Java 中做的最好的事情就是连接到一个不存在的主机。您不能只尝试连接到本地网络上不存在的 IP,因为本地以太网硬件可能会更快地失败。您想要的是连接到您知道不存在的远程网络上的无效 IP。选择与您的本地网络不对应的 10-net 地址可能会起作用。

    蹩脚的答案,但我没有看到任何其他方式。

    【讨论】:

    • 谢谢格雷。这确实有帮助。也许捕捉这些东西的最好方法是使用 findbugs 之类的代码分析工具。我认为应该避免使用没有超时的连接版本。
    • 是的,同意。即使在 C 世界中,这种情况也已经存在很长时间了。默认的内核超时时间大约是几分钟,在 99% 的现代网络应用程序中,这实在是太长了。
    猜你喜欢
    • 2019-02-27
    • 2013-07-01
    • 1970-01-01
    • 2011-04-04
    • 1970-01-01
    • 2019-08-24
    • 1970-01-01
    • 2013-08-11
    • 2023-04-01
    相关资源
    最近更新 更多