12

我想要boolean isReachable(String host, int port)在以下条件下通过以下 JUnit 测试的最快、最准确的函数。超时值由 JUnit 测试本身指定,并且可能被视为“无法访问”。

请注意:所有答案必须与平台无关。这意味着这InetAddress.isReachable(int timeout)不起作用,因为它依赖端口7在 Windows 上执行 ping(ICMP ping 在 Windows 上是一个未记录的功能),并且此端口在此设置中被阻止。

局域网设置:

  • thisMachine( 192.168.0.100)
  • otherMachine( 192.168.0.200)
  • 没有机器被调用noMachine或没有 IP 192.168.0.222(总是无法访问)
  • 两台机器都在端口上运行 Apache Tomcat 8080;所有其他端口都无法访问(包括 port 7
  • example.com( 208.77.188.166) 在端口上运行网络服务器,80并且仅当 LAN 连接到 Internet 时才可访问

有时,LAN 与 Internet 断开连接,在这种情况下,只能访问由 IP 地址调用的本地计算机(所有其他计算机都无法访问;没有 DNS)。

所有测试都在thisMachine.

@Test(timeout=1600) // ~320ms per call (should be possible to do better)
public void testLocalhost() {
    // We can always reach ourselves.
    assertTrue(isReachable("localhost", 8080));
    assertTrue(isReachable("127.0.0.1", 8080));
    assertTrue(isReachable("thisMachine", 8080)); // Even if there's no DNS!
    assertTrue(isReachable("192.168.0.100", 8080));

    assertFalse(isReachable("localhost", 80)); // Nothing on that port.
}

@Test(timeout=5500) // ~1867ms per call (should be able to do better)
public void testLAN() {
    assertTrue(isReachable("192.168.0.200", 8080)); // Always connected to the LAN.
    assertFalse(isReachable("192.168.0.222", 8080)); // No such a machine.
    assertFalse(isReachable("noMachine", 8080)); // No such machine.
}

以下测试仅在 LAN与 Internet断开连接时运行。

@Test(timeout=5600) // ~1867ms per call (reasonable?)
public void testNoDNS() {
    assertFalse(isReachable("otherMachine", 8080)); // No DNS.
    assertFalse(isReachable("example.com", 80)); // No DNS & no Internet.
    assertFalse(isReachable("208.77.188.166", 80)); // No Internet.
}

以下测试仅在 LAN连接到 Internet 时运行。

@Test(timeout=5600) // ~1867ms per call (reasonable?)
public void testHaveDNS() {
    assertTrue(isReachable("otherMachine", 8080)); // DNS resolves local names.
    assertTrue(isReachable("example.com", 80)); // DNS available.
    assertTrue(isReachable("208.77.188.166", 80)); // Internet available.
}
4

6 回答 6

6

Firstly you need to recognise that you have potentially conflicting requirements; IP sockets are not time deterministic. The quickest you can ever detect unreachability is after your elapsed timeout. You can only detect reachability quicker.

Assuming reachability/isReachable is your real objective, you should just use a straightforward non-blocking socket IO as shown in the Java Ping simulator, the example connects to the time service but would work equally well on 8080.

于 2008-10-14T10:24:20.733 回答
1

如果您想测试是否可以连接到 Web 服务器,您还可以根据主机名和端口号创建一个URL ,并使用它来创建一个URLConnection检查连接方法的结果(包括异常)应该告诉您是否网络服务器是可访问的。

于 2008-10-14T07:08:40.177 回答
0

如果您需要在很短的时间内对大量主机执行此操作,我会考虑使用fping之类的工具来代替 - shell out 来执行它并在输出返回时解析输出。fping 一次运行大量并行查询,所以理论上你可以在一分钟内检查几千台主机(我认为限制是 4096?)

于 2008-10-15T16:52:48.280 回答
0

不确定这有多实用。

怎么样做相当于traceroute(windows上的tracert),一旦你成功了,你就可以继续了。

在企业网络中,我看到 ICMP(ping) 被管理员阻止但通常,tracert 仍然有效。如果您能找到一种快速的方法来完成 tracert 的工作,那应该可以解决问题吗?

祝你好运!

于 2008-10-12T04:08:23.567 回答
0

主机可用性的速率确定步骤不在您自己的代码中,而是在 netlag 中。您必须等待主机响应,这可能需要一些时间。如果您的程序在等待响应时阻塞,则可能是一个问题。我通过将每个主机创建为一个对象来解决这个问题,每个主机都有自己的线程方法来检查可用性。在我自己的情况下,我跟踪了 40 个主机。我的主程序每 20 秒循环一次由 40 个机器对象组成的数组,并在每个对象上调用适当的方法来检查可用性。由于每个机器对象都会产生自己的线程来执行此操作,因此所有 40 台机器都会同时被询问,并且每台机器的响应时间(最多 500 毫秒)都不是问题。

于 2011-04-29T04:23:07.747 回答
0

我最近的解决方案取决于在执行连接时使用具有 3000 毫秒超时的TimedSocket源代码)。

时间:

  • 1406 毫秒:testLocalHost()
  • 5280 毫秒:testLAN()

甚至无法让这些正常工作:

  • testNoDNS()
  • testHaveDNS()
于 2008-10-12T03:54:20.710 回答