Was ist der schnellste Weg, um einen nicht erreichbaren Host in Java zu erkennen?

Ich möchte die schnellste und genaueste Funktionboolean isReachable(String host, int port) Dies besteht die folgenden JUnit-Tests unter den folgenden Bedingungen. Zeitlimitwerte werden vom JUnit-Test selbst angegeben und können als "nicht erreichbar" eingestuft werden.

Bitte beachten Sie: Alle Antworten müssen plattformunabhängig sein. Das bedeutet, dassInetAddress.isReachable(int timeout) wird nicht funktionieren, da es auf port angewiesen ist7 unter Windows einen Ping durchführen (ICMP-Ping ist unter Windows eine undokumentierte Funktion), und dieser Port ist in diesem Setup blockiert.

LAN-Setup:

thisMachine (192.168.0.100)otherMachine (192.168.0.200)Nein Maschine heißtnoMachine oder hat die IP192.168.0.222 (immer nicht erreichbar)Auf beiden Computern wird Apache Tomcat auf dem Port ausgeführt8080; Alle anderen Ports sind nicht erreichbar (einschließlich Port7)example.com (208.77.188.166) läuft ein Webserver auf Port80 und ist nur erreichbar, wenn das LAN mit dem Internet verbunden ist

Gelegentlich wird das LAN vom Internet getrennt. In diesem Fall sind nur lokale Computer erreichbar, die über die IP-Adresse angerufen werden (alle anderen sind nicht erreichbar; es gibt kein DNS).

Alle Tests werden ausgeführtthisMachine.

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

Der folgende Test wird nur ausgeführt, wenn das LAN istgetrennt aus dem 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.
}

Der folgende Test wird nur ausgeführt, wenn das LAN istin Verbindung gebracht in das 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.
}

Antworten auf die Frage(6)

Ihre Antwort auf die Frage