InetAddress byName = InetAddress.getByName("173.39.161.140");
System.out.println(byName);
System.out.println(byName.isReachable(1000));
Warum kehrt isReachable
zurück false
? Ich kann die IP anpingen.
InetAddress byName = InetAddress.getByName("173.39.161.140");
System.out.println(byName);
System.out.println(byName.isReachable(1000));
Warum kehrt isReachable
zurück false
? Ich kann die IP anpingen.
Antworten:
Die "isReachable" -Methode hat sich in vielen Fällen für mich nicht gelohnt . Sie können nach unten scrollen, um meine Alternative zum einfachen Testen zu sehen, ob Sie online sind und externe Hosts auflösen können (z. B. google.com). Dies scheint im Allgemeinen auf * NIX-Computern zu funktionieren.
Das Thema
Darüber wird viel geredet:
Hier sind andere, ähnliche Fragen:
Und sogar ein gemeldeter Fehler in dieser Angelegenheit:
Teil 1: Ein reproduzierbares Beispiel für das Problem
Beachten Sie, dass dies in diesem Fall fehlschlägt.
//also, this fails for an invalid address, like "www.sjdosgoogle.com1234sd"
InetAddress[] addresses = InetAddress.getAllByName("www.google.com");
for (InetAddress address : addresses) {
if (address.isReachable(10000))
{
System.out.println("Connected "+ address);
}
else
{
System.out.println("Failed "+address);
}
}
//output:*Failed www.google.com/74.125.227.114*
Teil 2: Eine hackige Problemumgehung
Alternativ können Sie dies tun:
// in case of Linux change the 'n' to 'c'
Process p1 = java.lang.Runtime.getRuntime().exec("ping -n 1 www.google.com");
int returnVal = p1.waitFor();
boolean reachable = (returnVal==0);
Mit der Ping- Option -c kann Ping einfach einmal versuchen, den Server zu erreichen (im Gegensatz zu dem unendlichen Ping, den wir am Terminal gewohnt sind).
Dies gibt 0 zurück, wenn der Host erreichbar ist . Andernfalls erhalten Sie "2" als Rückgabewert.
Viel einfacher - aber natürlich plattformspezifisch. Die Verwendung dieses Befehls kann mit gewissen Einschränkungen verbunden sein - aber ich finde, dass er auf meinen Computern funktioniert.
BITTE Beachten Sie Folgendes: 1) Diese Lösung entspricht nicht der Produktionsqualität. Es ist ein bisschen ein Hack. Wenn Google nicht verfügbar ist oder Ihr Internet vorübergehend langsam ist oder wenn Ihre Berechtigungen / Systemeinstellungen lustig sind, kann dies zu falschen Negativen führen (dh es kann fehlschlagen, obwohl die Eingabeadresse erreichbar ist). 2) Der isReachable-Fehler ist ein offenes Problem. Auch hier gibt es mehrere Online-Ressourcen, die darauf hinweisen, dass es zum Zeitpunkt des Schreibens keine "perfekte" Möglichkeit gibt, dies zu tun, da die JVM versucht, Hosts zu erreichen. Ich denke, es handelt sich um eine plattformspezifische Aufgabe, die zwar einfach ist , wurde von der JVM noch nicht ausreichend abstrahiert.
isReachable
mir werde ich gescheitert und mit Ping bekomme ich icmp nicht erlaubt? Wissen Sie, wie Sie jetzt damit umgehen sollen?
public boolean waitFor(long timeout, TimeUnit unit)
in java.lang.Process (@since 1.8)
isReachable
ist jetzt Tage zuverlässiger.
Ich kam hierher, um eine Antwort auf dieselbe Frage zu erhalten, war jedoch mit keiner der Antworten zufrieden, da ich nach einer plattformunabhängigen Lösung suchte. Hier ist der Code, den ich geschrieben habe und der plattformunabhängig ist, aber Informationen über jeden offenen Port auf dem anderen Computer erfordert (den wir die meiste Zeit haben).
private static boolean isReachable(String addr, int openPort, int timeOutMillis) {
// Any Open port on other machine
// openPort = 22 - ssh, 80 or 443 - webserver, 25 - mailserver etc.
try {
try (Socket soc = new Socket()) {
soc.connect(new InetSocketAddress(addr, openPort), timeOutMillis);
}
return true;
} catch (IOException ex) {
return false;
}
}
InetAddress.isReachable()
bereits über Port 7 geschieht, mit der Ausnahme, dass letzterer intelligenter ist, was die verschiedenen möglichen IOExceptions
in Bezug auf die Erreichbarkeit bedeuten.
InetAddress.isReachable()
das Port-Argument in die Standardbibliothek aufgenommen würde. Ich frage mich, warum es nicht enthalten war?
Wenn Sie nur überprüfen möchten, ob eine Internetverbindung besteht, verwenden Sie diese Methode. Bei Internetverbindung wird true zurückgegeben. Dies ist vorzuziehen, wenn Sie die Adresse der Site verwenden, die Sie über das Programm verbinden möchten.
public static boolean isInternetReachable()
{
try {
//make a URL to a known source
URL url = new URL("http://www.google.com");
//open a connection to that source
HttpURLConnection urlConnect = (HttpURLConnection)url.openConnection();
//trying to retrieve data from the source. If there
//is no connection, this line will fail
Object objData = urlConnect.getContent();
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
Ich erwähne es nur explizit, da die anderen Antworten dies nicht tun. Der Ping-Teil von isReachable () erfordert Root-Zugriff unter Unix. Und wie von bestsss in 4779367 hervorgehoben :
Und wenn Sie fragen, warum Ping von Bash nicht funktioniert, muss es auch so sein. Mach das ls -l / bin / ping.
Da die Verwendung von root in meinem Fall keine Option war, bestand die Lösung darin, den Zugriff auf Port 7 in der Firewall auf den bestimmten Server zuzulassen, an dem ich interessiert war.
Ich bin mir nicht sicher, wie der Stand war, als die ursprüngliche Frage 2012 gestellt wurde.
In der jetzigen Form wird Ping als Root ausgeführt. Durch die Autorisierung der ausführbaren Ping-Datei sehen Sie das Flag + s und den Prozess, der zu root gehört, was bedeutet, dass es als root ausgeführt wird. Führen Sie ls -liat aus, wo sich der Ping befindet, und Sie sollten ihn sehen.
Wenn Sie also InetAddress.getByName ("www.google.com"). IsReacheable (5000) als root ausführen, sollte true zurückgegeben werden.
Sie benötigen die entsprechenden Berechtigungen für den Raw-Socket, der von ICMP verwendet wird (das von Ping verwendete Protokoll).
InetAddress.getByName ist genauso zuverlässig wie Ping, aber Sie benötigen die entsprechenden Berechtigungen für den Prozess, damit er ordnungsgemäß ausgeführt wird.
Ich würde vorschlagen, dass der EINZIGE zuverlässige Weg zum Testen einer Internetverbindung darin besteht, eine Verbindung herzustellen UND eine Datei herunterzuladen ODER die Ausgabe eines Betriebssystem-Ping-Aufrufs über exec () zu analysieren. Sie können sich nicht auf den Exit-Code für Ping verlassen und isReachable () ist Mist.
Sie können sich nicht auf einen Ping-Exit-Code verlassen, da dieser 0 zurückgibt, wenn der Ping-Befehl korrekt ausgeführt wird. Leider wird Ping korrekt ausgeführt, wenn es den Zielhost nicht erreichen kann, aber einen "Zielhost nicht erreichbar" von Ihrem ADSL-Heimrouter erhält. Dies ist eine Art Antwort, die als erfolgreicher Treffer behandelt wird. Beenden Sie daher den Code = 0. Sie müssen jedoch hinzufügen, dass dies auf einem Windows-System erfolgt. Nicht geprüft * nixes.
private boolean isReachable(int nping, int wping, String ipping) throws Exception {
int nReceived = 0;
int nLost = 0;
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec("ping -n " + nping + " -w " + wping + " " + ipping);
Scanner scanner = new Scanner(process.getInputStream());
process.waitFor();
ArrayList<String> strings = new ArrayList<>();
String data = "";
//
while (scanner.hasNextLine()) {
String string = scanner.nextLine();
data = data + string + "\n";
strings.add(string);
}
if (data.contains("IP address must be specified.")
|| (data.contains("Ping request could not find host " + ipping + ".")
|| data.contains("Please check the name and try again."))) {
throw new Exception(data);
} else if (nping > strings.size()) {
throw new Exception(data);
}
int index = 2;
for (int i = index; i < nping + index; i++) {
String string = strings.get(i);
if (string.contains("Destination host unreachable.")) {
nLost++;
} else if (string.contains("Request timed out.")) {
nLost++;
} else if (string.contains("bytes") && string.contains("time") && string.contains("TTL")) {
nReceived++;
} else {
}
}
return nReceived > 0;
}
nping ist die Anzahl der Versuche, IP (Pakete) zu pingen, wenn Sie ein ausgelastetes Netzwerk oder Systeme haben, wählen Sie größere nping-Nummern.
wping ist die Zeit, die auf pong von ip wartet. Sie können 2000 ms
für die Verwendung dieser Methode einstellen. Sie können Folgendes schreiben:
isReachable(5, 2000, "192.168.7.93");
Oder auf folgende Weise:
public static boolean exists(final String host)
{
try
{
InetAddress.getByName(host);
return true;
}
catch (final UnknownHostException exception)
{
exception.printStackTrace();
// Handler
}
return false;
}
InetAddress.isReachable
ist flappy und gibt manchmal nicht erreichbare Adressen zurück, die wir anpingen können.
Ich habe folgendes versucht:
ping -c 1 <fqdn>
und überprüfen Sie die exit status
.
Funktioniert für alle Fälle, in denen ich versucht habe, wo InetAddress.isReachable
es nicht funktioniert.
Da Sie den Computer anpingen können, sollte Ihr Java-Prozess mit ausreichenden Berechtigungen ausgeführt werden, um die Überprüfung durchzuführen. Wahrscheinlich aufgrund der Verwendung von Ports im unteren Bereich. Wenn Sie Ihr Java-Programm mit sudo / superuser ausführen, funktioniert es bestimmt.