Internetverbindung mit Java erkennen

Mögliche Duplikate:
Wie überprüft man, ob eine Internetverbindung in Java vorhanden ist?

Ich möchte sehen, ob jemand eine einfache Möglichkeit hat zu erkennen, ob es eine Internetverbindung bei der Verwendung von Java gibt. Die aktuelle App verwendete die “InternetGetConnectedState” -Methode in der WinInit-DLL für Windows, aber meine App muss für den Mac-Betrieb plattformübergreifend sein und auf diese Weise nicht funktionieren. Ich kenne JNI überhaupt nicht, um DLLs in Java zu verwenden, und es wurde schnell frustrierend.

Ich konnte nur daran denken, eine URL-Verbindung zu einer Website zu öffnen, und wenn das fehlschlägt, gebe false zurück. Mein anderer Weg ist unten, aber ich wusste nicht, ob das im Allgemeinen stabil war. Wenn ich mein Netzwerkkabel abziehe, erhalte ich eine UnknownHostException, wenn ich versuche, die InetAddress zu erstellen. Ansonsten, wenn das Kabel angeschlossen ist, bekomme ich ein gültiges InetAddress-Objekt. Ich habe den untenstehenden Code noch nicht auf einem Mac getestet.

Vielen Dank für Beispiele oder Ratschläge, die Sie zur Verfügung stellen können.

UPDATE: Der letzte Codeblock befindet sich unten. Ich entschied mich, den Rat einer HTTP-Anfrage (in diesem Fall Google) zu nehmen. Es ist einfach und sendet eine Anfrage an die Website für Daten zurückgegeben werden. Wenn ich keinen Inhalt von der Verbindung bekomme, gibt es kein Internet.

public static boolean isInternetReachable() { try { InetAddress address = InetAddress.getByName("java.sun.com"); if(address == null) { return false; } } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); return false; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); return false; } return true; } 

Endgültiger Code Block:

 //checks for connection to the internet through dummy request 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 (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); return false; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); return false; } return true; } 

Das ist ein vollkommen vernünftiger Ansatz zur Lösung des Problems. Das Schlimme ist, dass Sie wirklich DNS testen, anstatt das gesamte Netzwerk zu testen, aber in der Praxis können Sie oft damit umgehen, dass Sie diese als gleichwertig behandeln.

Die andere Sache, die Sie sich merken sollten, ist, dass Sie eine Systemeigenschaft setzen müssen, um das DNS-Caching in der Java-Laufzeitumgebung zu deaktivieren. Andernfalls kann es weiterhin melden, dass das Netzwerk auf zwischengespeicherten Daten basiert (obwohl es ausgefallen ist).

Ein anderer Ansatz wäre, eine HTTP-Anfrage für eine solche Netzwerkadresse zu öffnen.

Ich muss hinzufügen, dass, obwohl der letzte Codeblock oben gut ist, es einen Fehler hat – es ist möglich, dass es sehr lange dauert, die angegebene Adresse zu kontaktieren, aber die Adresse ist immer noch erreichbar.

In meinem Fall würde die Methode beim Testen mit einer Adresse true zurückgeben, aber 10 Sekunden oder länger dauern, um eine Antwort zu erhalten. In diesem Fall war der Server erreichbar, aber für keine nützlichen Zwecke, da die Verbindung so langsam war. Dies tritt auf, weil das Standardtimeout für HttpURLConnection 0 oder unendlich ist.

Aus diesem Grund würde ich Ihnen empfehlen, den UI-Thread zu überprüfen und urlConnect.setConnectTimeout(1000); hinzuzufügen urlConnect.setConnectTimeout(1000); vor dem Aufruf von urlConnect.getContent();

Auf diese Weise wissen Sie, dass die Adresse erreichbar ist und dass das Herunterladen einer 10k-Datei nicht 5 Jahre dauert.

(Sie können natürlich die Timeout-Zeit ändern, um Ihre Anforderungen zu erfüllen)

Ich würde auch empfehlen, eine generische Adresse (google.com usw.) nicht zu überprüfen, es sei denn, Ihr Programm greift in der Regel auf mehr als ein paar Domains zu. Wenn Sie nur auf ein oder zwei zugreifen, überprüfen Sie diese Domäne.

Beachten Sie, dass es false zurückgeben könnte, wenn java.sun.com nicht antwortet! In diesem Fall sollten Sie eine andere Website überprüfen, um sicherzugehen.

Habe das nicht getestet, aber ich schlage vor, java.net.NetworkInterface.getNetworkInterfaces () zu betrachten. Dies gibt eine Enumeration aller Netzwerkschnittstellen auf dem Computer zurück, oder Null, wenn keine vorhanden sind.

Ich bin nicht sicher, ob es sicher ist anzunehmen, dass eine Antwort ungleich Null eine gültige Netzwerkverbindung gewährleistet – abhängig von Ihren Bedürfnissen müssen Sie möglicherweise Loopback-Adressen herausfiltern (was Sie mit java.net tun könnten) .NetworkInterface.getInetAddresses () für jedes zurückgegebene NetworkInterface und dann den Aufruf von InetAddress.isLoopbackAddress ().)

Die einzige Möglichkeit, sicher zu sein, dass Sie einen bestimmten Dienst erreichen können, besteht darin, eine Dummy-Anfrage an diesen Dienst zu richten. Pings können durch Firewalls blockiert werden. Einige Server sind möglicherweise erreichbar, andere nicht. Wenn Sie mit einem Webservice sprechen müssen, müssen Sie eine statische Seite für diese Anfragen zurückgeben.

Denken Sie auch daran, den Benutzer zu fragen, bevor Sie versuchen, ihn zu erreichen.

Die Frage hat keine wirkliche Bedeutung. Es gibt keine “Verbindung zum Internet”. Sie müssen versuchen , einen zu erstellen . Die Windows-API, auf die verwiesen wird, sagt Ihnen nur, ob Ihr Modem angewählt ist oder nicht, und ich habe gesehen, dass es tatsächlich Einwahl verursacht , was nicht gerade die Idee ist. Nicht, dass ich in den letzten 8 Jahren oder so eine Einwahl hatte.

Ein Problem mit der ersten Lösung besteht darin, dass InetAddress über einen Cache verfügt. Wenn Sie die Verbindung für die nächsten Aufrufe verlieren, wird der Name über den Java-Cache aufgetriggers. Mit dem URL-Verbindungsansatz haben Sie das Problem, dass Sie getContent verwenden, der HTML holen soll, damit Sie Daten verbrauchen. Wenn die Aufrufe sehr oft ausgeführt werden, könnte das ein Problem sein (mehr, wenn Sie auf dem Gerät, auf dem die Software ausgeführt wird, keinen unbegrenzten Datentarif haben).

Ich denke, die beste Lösung wäre, eine TCP-Verbindung zu dem 80-Port herzustellen und sie unmittelbar nach einer erfolgreichen Verbindung zu schließen. Das würde sich wie der endgültige Code verhalten, hätte aber viel weniger Verkehr.