2013-08-19 6 views
7

Ich versuche, einen Host und haben den folgenden Codebeste Alternative für InetAddress.getByName (Host) .isReachable (Timeout)

if(!InetAddress.getByName(host).isReachable(TIMEOUT)){ 
    throw new Exception("Host does not exist::"+ hostname); 
} 

Der Hostname ich in der Lage zu erreichen, bin aus den Fenstern pingen, und haben auch eine tracert darauf und es gibt alle Pakete zurück. Aber Java verwirft die Ausnahme "Host existiert nicht ::";

Der Timeout-Wert, den ich experimentierte von 2000ms, bis 5000ms. Ich habe auch 3000 probiert. Was ist die Ursache für dieses Problem, das ich nicht verstehen kann? Ich recherchierte im Internet und einige sagen, dass InetAddress.getByName (Host) .isReachable (Zeit) ist nicht zuverlässig und verhält sich entsprechend dem internen System.

Was ist die beste Alternative für das, wenn dies wahr ist. Bitte vorschlagen.

+0

Der Host, mit dem ich teste, ist erreichbar und ich kann es in Windows anpingen. –

Antwort

14

Entweder öffnen Sie eine TCP-Socket an einen Port Sie denken, offen ist (22 für Linux, 139 für Windows usw.)

public static boolean isReachableByTcp(String host, int port, int timeout) { 
    try { 
     Socket socket = new Socket(); 
     SocketAddress socketAddress = new InetSocketAddress(host, port); 
     socket.connect(socketAddress, timeout); 
     socket.close(); 
     return true; 
    } catch (IOException e) { 
     return false; 
    } 
} 

Oder etwas Hack verwenden, um einen tatsächlichen Ping zu senden. (Inspiriert von hier: http://www.inprose.com/en/content/icmp-ping-in-java)

public static boolean isReachableByPing(String host) { 
    try{ 
     String cmd = ""; 

     if(System.getProperty("os.name").startsWith("Windows")) 
      cmd = "cmd /C ping -n 1 " + host + " | find \"TTL\""; 
     else 
      cmd = "ping -c 1 " + host; 

     Process myProcess = Runtime.getRuntime().exec(cmd); 
     myProcess.waitFor(); 

     return myProcess.exitValue() == 0; 
    } catch(Exception e) { 
     e.printStackTrace(); 
     return false; 
    } 
} 

Same Hack für Android kann here finden:

+1

Das Problem mit "ping -n 1" unter Windows ist, dass der "Zielhost nicht erreichbar" ist. Ergebnis gibt einen Exit-Code von 0 zurück, was viele falsche Positive erzeugt. –

+1

wie kann ich das mit android verwenden? –

+0

Ping mit Android: http://stackoverflow.com/questions/3905358/how-to-ping-external-ip-from-java-android – Shloim

0

Ich habe festgestellt, dass ping -n 1 hostname entweder nicht zuverlässig ist. Wenn Sie Reply from X.X.X.X: Destination host unreachable. erhalten, gibt der Befehl tatsächlich einen Exit-Code von 0, wodurch Sie viele falsche Positive erhalten.

Die Lösung besteht darin, im Ergebnis nach dem String "TTL" zu suchen, da dieser nur existiert, wenn Sie einen erfolgreichen Ping erhalten. Da der Befehl eine Pipe hat, müssen Sie auch cmd /C verwenden. Hier

ist ein Beispiel (Windows):

public boolean isReachable(String hostname) throws IOException, InterruptedException { 
    Process p = Runtime.getRuntime().exec(
      "cmd /C ping -n 1 "+hostname+" | find \"TTL\"" 
    ); 
    return (p.waitFor() == 0); 
} 

Ich bin nicht sicher, ob der Unix-äquivalent, und nicht über eine Unix-Maschine zu testen.

0

Für Android-Entwickler: Die obige Methode funktioniert nicht, wenn inet nicht verfügbar ist (genauer gesagt, wenn DNS-Cache in einem Timeout ausgeführt wird); Was ich gefunden habe: DSN Lookup dauert immer ca. 1 Minute.

ist mein Code wie folgt aus:

TIMEOUT = 5000; 
socket.connect(new InetSocketAddress(ServerDomainName, Port), TIMEOUT); 

Es wird erwartet, dass connect innerhalb von etwa 5 Sekunden, um eine Timeout-Ausnahme auslöst, aber die Zeit betrug 65 Sekunden, wenn inet nicht erreichbar war (jemand beschreibt es als Fälschung inet Verbindung : Connectivity sagt verbunden, aber inet ist nicht erreichbar).

Verwandte Themen