web-dev-qa-db-fra.com

Comment vérifier si une connexion Internet est présente en Java?

Comment vérifier si vous pouvez vous connecter à Internet via Java? Une façon serait:

final URL url = new URL("http://www.google.com");
final URLConnection conn = url.openConnection();
... if we got here, we should have net ...

Mais y a-t-il quelque chose de plus approprié pour effectuer cette tâche, en particulier si vous devez effectuer des contrôles consécutifs très souvent et une perte de connexion Internet est hautement probable?

55
Chris

Vous devez vous connecter à l'endroit où votre application a réellement besoin. Sinon, vous testez si vous avez une connexion à un lieu non pertinent (Google dans ce cas).

En particulier, si vous essayez de parler à un service Web et que vous en contrôlez le service Web, il serait judicieux de recourir à une méthode Web peu coûteuse "obtenir l'état". De cette façon, vous avez une bien meilleure idée du potentiel de votre "vrai" appel.

Dans d'autres cas, le simple fait d'ouvrir une connexion à un port qui devrait être ouvert peut suffire - ou d'envoyer un ping. InetAddress.isReachable est peut-être une API appropriée à vos besoins ici.

46
Jon Skeet

Le code que vous avez fourni, plus un appel à connect devrait suffire. Donc oui, il se peut que Google ne soit pas disponible mais que vous deviez contacter un autre site, mais quelle est sa probabilité? En outre, ce code ne doit être exécuté que lorsque vous ne parvenez pas à accéder à votre ressource externe (dans un bloc catch pour essayer de déterminer la cause de la défaillance). Je dirais donc que si votre ressource externe d’intérêt et Google ne sont pas disponibles Il est probable que vous rencontriez un problème de connectivité Internet.

private static boolean netIsAvailable() {
    try {
        final URL url = new URL("http://www.google.com");
        final URLConnection conn = url.openConnection();
        conn.connect();
        conn.getInputStream().close();
        return true;
    } catch (MalformedURLException e) {
        throw new RuntimeException(e);
    } catch (IOException e) {
        return false;
    }
}
19

Des personnes ont suggéré d'utiliser INetAddress.isReachable. Le problème est que certains sites configurent leurs pare-feu pour bloquer les messages ICMP Ping. Donc, un "ping" peut échouer même si le service Web est accessible. 

Et bien sûr, l'inverse est également vrai. Un hôte peut répondre à un ping même si le serveur Web est en panne.

Et bien sûr, une machine peut ne pas être en mesure de se connecter directement à certains (ou à tous) serveurs Web en raison des restrictions du pare-feu local.

Le problème fondamental est que "pouvoir se connecter à Internet" est une question mal définie, et ce genre de chose est difficile à tester sans:

  1. des informations sur la machine de l'utilisateur et l'environnement de réseau "local", et
  2. informations sur les éléments auxquels l'application doit accéder.

En règle générale, la solution la plus simple consiste pour une application à essayer d'accéder à tout ce dont elle a besoin et à faire appel à l'intelligence humaine pour établir le diagnostic.

17
Stephen C

Si vous utilisez Java 6, vous pouvez utiliser NetworkInterface pour vérifier les interfaces réseau disponibles . I.e. quelque chose comme ça:

Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
  NetworkInterface interf = interfaces.nextElement();
  if (interf.isUp() && !interf.isLoopback())
    return true;
}

Je n'ai pas encore essayé moi-même.

7
Kutzi

Ce code devrait faire le travail de manière fiable.

Notez que lorsque vous utilisez l'instruction try-with-resources , il n'est pas nécessaire de fermer les ressources.

import Java.io.IOException;
import Java.net.InetSocketAddress;
import Java.net.Socket;
import Java.net.UnknownHostException;

public class InternetAvailabilityChecker
{
    public static boolean isInternetAvailable() throws IOException
    {
        return isHostAvailable("google.com") || isHostAvailable("Amazon.com")
                || isHostAvailable("facebook.com")|| isHostAvailable("Apple.com");
    }

    private static boolean isHostAvailable(String hostName) throws IOException
    {
        try(Socket socket = new Socket())
        {
            int port = 80;
            InetSocketAddress socketAddress = new InetSocketAddress(hostName, port);
            socket.connect(socketAddress, 3000);

            return true;
        }
        catch(UnknownHostException unknownHost)
        {
            return false;
        }
    }
}
6
BullyWiiPlaza

Ce code:

"127.0.0.1".equals(InetAddress.getLocalHost().getHostAddress().toString());

Renvoie - pour moi - true si hors ligne, et false sinon. (bon, je ne sais pas si cela est vrai pour tous les ordinateurs). 

Cela fonctionne beaucoup plus rapidement que les autres approches, ici.


EDIT: J'ai trouvé que cela ne fonctionne que si le "commutateur à bascule" (sur un ordinateur portable), ou une autre option définie par le système, pour la connexion Internet, est désactivée. En effet, le système lui-même sait qu'il ne faut rechercher aucune adresse IP.

6
Mordechai

Le code utilisant NetworkInterface pour attendre le réseau a fonctionné pour moi jusqu'à ce que je passe d'une adresse réseau fixe à un serveur DHCP. Une légère amélioration le fait aussi fonctionner avec DHCP: 

Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
    NetworkInterface interf = interfaces.nextElement();
    if (interf.isUp() && !interf.isLoopback()) {
    List<InterfaceAddress> adrs = interf.getInterfaceAddresses();
    for (Iterator<InterfaceAddress> iter = adrs.iterator(); iter.hasNext();) {
        InterfaceAddress adr = iter.next();
        InetAddress inadr = adr.getAddress();
        if (inadr instanceof Inet4Address) return true;
            }
    }
}

Cela fonctionne pour Java 7 dans openSuse 13.1 pour le réseau IPv4. Le problème avec le code d'origine est que, même si l'interface était opérationnelle après la reprise de la suspension, une adresse réseau IPv4 n'était pas encore attribuée. Après avoir attendu cette affectation, le programme peut se connecter aux serveurs. Mais je ne sais pas quoi faire dans le cas d'IPv6. 

4
harald
URL url=new URL("http://[any domain]");
URLConnection con=url.openConnection();

/*now errors WILL arise here, i hav tried myself and it always shows "connected" so we'll open an InputStream on the connection, this way we know for sure that we're connected to d internet */

/* Get input stream */
con.getInputStream();

Mettez les déclarations ci-dessus dans des blocs catch try et si une exception est capturée, cela signifie qu'aucune connexion Internet n'est établie. :-)

4
Rushil

InetAddress.isReachable retourne parfois false s'il existe une connexion Internet. 

Une autre méthode pour vérifier la disponibilité d'Internet en Java est la suivante: Cette fonction crée un vrai ping ICMP ECHO.

public static boolean isReachableByPing(String Host) {
     try{
                String cmd = "";
                if(System.getProperty("os.name").startsWith("Windows")) {   
                        // For Windows
                        cmd = "ping -n 1 " + Host;
                } else {
                        // For Linux and OSX
                        cmd = "ping -c 1 " + Host;
                }

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

                if(myProcess.exitValue() == 0) {

                        return true;
                } else {

                        return false;
                }

        } catch( Exception e ) {

                e.printStackTrace();
                return false;
        }
}
4
Shibina EC

Je le décompose généralement en trois étapes.

  1. Je vois d’abord si je peux résoudre le nom de domaine en une adresse IP.
  2. J'essaie ensuite de me connecter via TCP (port 80 et/ou 443) et de fermer en douceur.
  3. Enfin, je vais émettre une requête HTTP et vérifier la réponse 200.

Si cela échoue à tout moment, je fournis le message d'erreur approprié à l'utilisateur.

4
Marcus Adams
public boolean checkInternetConnection()
{
     boolean status = false;
     Socket sock = new Socket();
     InetSocketAddress address = new InetSocketAddress("www.google.com", 80);

     try
     {
        sock.connect(address, 3000);
        if(sock.isConnected()) status = true;
     }
     catch(Exception e)
     {
         status = false;       
     }
     finally
     {
        try
         {
            sock.close();
         }
         catch(Exception e){}
     }

     return status;
}
2
Zoka

Ce code est contenu dans une classe de test jUnit que j’utilise pour vérifier si une connexion est disponible. Je reçois toujours une connexion, mais si vous vérifiez la longueur du contenu, il devrait être -1 si vous ne le connaissez pas 

  try {
    URL url = new URL("http://www.google.com");
    URLConnection connection = url.openConnection();

    if(connection.getContentLength() == -1){
          fail("Failed to verify connection");
    }
  } 
  catch (IOException e) {
      fail("Failed to open a connection");
      e.printStackTrace();
  }
2
blue-sky

1) Déterminez où votre application doit se connecter.

2) Configurez un processus de travail pour vérifier InetAddress.isReachable pour surveiller la connexion à cette adresse.

2
Justin Niessner

Il existe également une option de gradation --offline qui peut entraîner le comportement souhaité.

0
Dirk Hoffmann

Le code suivant nous permet d’obtenir l’état du réseau sur notre appareil Android. 

public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView mtv=findViewById(R.id.textv); ConnectivityManager connectivityManager= (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if(((Network)connectivityManager.getActiveNetwork())!=null) mtv.setText("true"); else mtv.setText("fasle"); } } }

0
edwin