2008-10-12 89 views
11

我想要在下面的条件下通过以下JUnit测试的最快和最准确的函数boolean isReachable(String host, int port)。超时值由JUnit测试本身指定,并可能被视为“无法访问”。什么是在Java中检测无法访问的主机的最快方法?

请注意:所有答案必须是平台无关的。这意味着,InetAddress.isReachable(int timeout)是行不通的,因为它依赖于端口7做Windows上的平(ICMP的ping是Windows上的无证功能),而这个端口被阻止在此设置。

LAN设置:

  • thisMachine192.168.0.100
  • otherMachine192.168.0.200
  • 没有机器叫做noMachine或具有
  • 两台机器正在运行的IP 192.168.0.222(总是无法访问)端口8080上的Apache Tomcat;所有其它端口都无法访问(包括端口7
  • example.com208.77.188.166)正在运行在端口80一个网络服务器和当LAN连接到因特网

有时候是仅可到达的,LAN从断开互联网在这种情况下只有通过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. 
} 

以下测试仅运行。

@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是连接到因特网以下测试仅运行。

@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. 
} 

回答

0

我最近的解决方案取决于使用TimedSocketsource code)与3000ms在执行连接超时。

时序:

  • 1406ms:testLocalHost()
  • 5280ms:testLAN()

甚至不能得到这些正常工作:

  • testNoDNS()
  • testHaveDNS()
0

不知道这是多么实际。

如何做相当于traceroute(windows上的tracert),一旦你获得成功,你可以继续。

在企业网络中,我见过ICMP(ping)被管理员阻止,但通常情况下,tracert仍然有效。如果你能想出一个快速的方法去做tracert的工作,那应该可以做到吗?

祝你好运!

1

如果你想测试你是否可以连接到Web服务器上,你还可以创建一个基于主机名和端口号URL并用它来创建一个URLConnectionconnect method的检查结果(包括异常)应告诉你网络服务器是否可达。

5

首先你需要认识到你有潜在冲突的要求; IP套接字不是时间确定性的。您可以检测到不可到达的最快速度是在您超时之后。您只能更快地检测到可达性。

假设可达/ isReachable是你真正的目标,你应该只使用一个简单的非阻塞IO插槽中所示的Java Ping模拟器,示例连接到时间服务,但将同样很好地工作在8080

0

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

0

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

相关问题