在 Java 中检测无法访问的主机的最快方法是什么? [英] What is the quickest way to detect an unreachable host in Java?

查看:62
本文介绍了在 Java 中检测无法访问的主机的最快方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I would like the fastest and most accurate function boolean isReachable(String host, int port) that passes the following JUnit tests under the conditions below. Timeout values are specified by the JUnit test itself, and may be considered "unreachable."

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

Please note: All answers must be platform-independent. This means that InetAddress.isReachable(int timeout) is not going to work, since it relies on port 7 to do a ping on Windows (ICMP ping being an undocumented function on Windows), and this port is blocked in this setup.

局域网设置:

  • 这台机器 (192.168.0.100)
  • otherMachine (192.168.0.200)
  • 没有机器被称为noMachine或有IP192.168.0.222(总是无法访问)
  • 两台机器都在端口 8080 上运行 Apache Tomcat;所有其他端口都无法访问(包括端口 7)
  • example.com (208.77.188.166) 在端口 80 上运行网络服务器,并且只有在 LAN 连接到互联网
  • thisMachine (192.168.0.100)
  • otherMachine (192.168.0.200)
  • no machine is called noMachine or has the IP 192.168.0.222 (always unreachable)
  • both machines are running Apache Tomcat on port 8080; all other ports are unreachable (including port 7)
  • example.com (208.77.188.166) is running a webserver on port 80 and is only reachable when the LAN is connected to the Internet

有时,LAN 与 Internet 断开连接,在这种情况下,只有通过 IP 地址调用的本地机器可以访问(所有其他机器都无法访问;没有 DNS).

Occasionally, the LAN is disconnected from the Internet in which case only local machines called by IP address are reachable (all others are unreachable; there's no DNS).

所有测试都在thisMachine上运行.

All tests are run on 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 与互联网断开连接时运行.

The following test is only run when the LAN is disconnected from the 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 时运行.

The following test is only run when the LAN is connected to the 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.
}

推荐答案

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

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.

假设reachability/isReachable是你的真正目标,你应该只使用一个简单的非阻塞套接字IO,如Java Ping 模拟器,该示例连接到时间服务,但在 8080 上也能正常工作.

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.

这篇关于在 Java 中检测无法访问的主机的最快方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆