2009-09-09 9 views
52

Come si controlla se è possibile connettersi a Internet tramite java? Un modo potrebbe essere:Come verificare se la connessione Internet è presente in java?

Ma c'è qualcosa di più appropriato per svolgere questo compito, soprattutto se avete bisogno di fare controlli consecutivi molto spesso e una perdita di connessione a Internet è altamente probabile?

+20

sì, ma questo "duplicato" ha accettato una risposta che non è nemmeno una soluzione così non si preoccupa – Chris

+0

La risposta a questo è la stessa di mamy altre domande della stessa forma. L'unico modo corretto per determinare se una risorsa è disponibile è provare a usarlo, nel corso normale dell'esecuzione, e far fronte all'errore come e quando accade. Qualsiasi altra tecnica è una forma o l'altra di cercare di predire il futuro. – EJP

risposta

44

È necessario connettersi al luogo richiesto dall'applicazione effettiva. Altrimenti stai verificando se hai una connessione a qualche parte irrilevante (Google in questo caso).

In particolare, se si sta tentando di parlare con un servizio Web e se si ha il controllo del servizio Web, sarebbe una buona idea disporre di una sorta di metodo web "ottieni lo stato" a buon mercato . In questo modo hai un'idea molto più precisa del fatto che la tua chiamata "reale" funzioni probabilmente.

In altri casi, è sufficiente aprire una connessione a una porta che dovrebbe essere aperta o inviare un ping. InetAddress.isReachable potrebbe essere un'API appropriata per le tue esigenze qui.

+3

Il collegamento a isReachable è andato alla classe sbagliata. È su http://java.sun.com/javase/6/docs/api/java/net/InetAddress.html#isReachable –

+12

e se ci si connette a una risorsa con cui si desidera comunicare e non riesce. come fai a sapere che era il problema del server di destinazione e non bcs non c'era connessione a Internet? così 'connettiti al luogo di cui necessita l'applicazione effettiva' non è in realtà una soluzione che non sarebbe un controllo affidabile – Chris

+4

@Chris: Dipende se ti interessa davvero quale sia il problema. Sono d'accordo sul fatto che puoi ottenere maggiori informazioni diagnostiche se (dopo un errore) ti connetti anche da qualche altra parte. Ma la parte più importante delle informazioni è sicuramente "Posso usare la risorsa che sto cercando di usare?" –

2

1) Individuare dove è necessario connettersi con l'applicazione.

2) Impostare un processo di lavoro per verificare InetAddress.isReachable per monitorare la connessione a tale indirizzo.

+0

processo di lavoro? –

17

Le persone hanno suggerito di utilizzare INetAddress.isRecondable. Il problema è che alcuni siti configurano i loro firewall per bloccare i messaggi Ping ICMP. Quindi un "ping" potrebbe fallire anche se il servizio web è accessibile.

E, naturalmente, è vero anche il contrario. Un host può rispondere a un ping anche se il server web non funziona.

E, naturalmente, una macchina potrebbe non essere in grado di connettersi direttamente a determinati (o tutti) server Web a causa delle restrizioni locali del firewall.

Il problema fondamentale è che "in grado di connettersi a Internet" è una domanda mal definita, e questo genere di cose è difficile da testare senza:

  1. informazioni sul computer dell'utente e il networking "locale" ambiente e
  2. informazioni su cosa l'app deve accedere.

Quindi, in genere, la soluzione più semplice è che un'applicazione cerchi solo di accedere a qualsiasi cosa abbia bisogno di accedere e ricorrere all'intelligenza umana per fare la diagnosi.

+0

bene, non mal definito. la domanda è solo "c'è internet" niente di più. – Chris

+2

Questo è il mio punto. La domanda "c'è internet" è mal definita. Leggi il testo sopra per esempi che hanno lo scopo di illustrare questo. –

+0

@Chris: "Internet" è mal definito. Essere in grado di arrivare a Google non significa che puoi necessariamente andare da qualsiasi altra parte, ad esempio. (Immagina se il server DNS non funziona, ma ti capita di avere una voce DNS nel tuo file hosts.) –

6

Se sei su java 6 puoi utilizzare NetworkInterface per verificare le interfacce di rete disponibili. I.e. qualcosa del genere:

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

Non ho ancora provato da solo.

+1

questo controlla solo che l'interfaccia sia abilitata. Non controlla la connessione internet. – siamii

+0

Tuttavia, l'interfaccia di rete in corso è un prerequisito per una connessione Internet. Penso che questo abbia senso come il primo passo di una soluzione più solida. Ti permette di vedere almeno se hai un'interfaccia di rete attiva senza inviare alcun traffico di rete. – adamfisk

+0

Quale non è quello che l'OP chiedeva. – EJP

4
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(); 

Mettere le dichiarazioni di cui sopra in blocchi catch try e se un'eccezione in catturato significa che non c'è alcuna connessione a Internet. :-)

4

Di solito scomposizione in tre passaggi.

  1. Prima vedo se riesco a risolvere il nome di dominio in un indirizzo IP.
  2. Quindi provo a connettermi tramite TCP (porta 80 e/o 443) e chiudere con garbo.
  3. Infine, emetterò una richiesta HTTP e ricontrollerò 200 risposte.

Se non riesce in qualsiasi momento, fornisco all'utente il messaggio di errore appropriato.

+0

Penso che questa possa essere una buona risposta, ma puoi approfondire, perché non è una buona risposta in questo momento. – Pacerier

6

Questo codice:

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

Returns - per me - true se non in linea, e false, in caso contrario. (beh, non so se questo è vero per tutti i computer).

Questo funziona molto più velocemente degli altri approcci, quassù.


EDIT: Ho trovato questo solo di lavoro, se l'opzione "interruttore flip" (su un computer portatile), o qualche altro sistema definite, per la connessione Internet, è spento. Cioè, il sistema stesso sa di non cercare alcun indirizzo IP.

+0

non funziona per "127.0.0.1" ma mostra risposta ad altro indirizzo IP raggiungibile –

+0

Funziona per me e mi piace e lo uso. Questo è un tipo di pre-controllo. Un controllo preliminare per garantire che l'interfaccia di rete sia connessa, che è possibile richiamare prima di verificare la connessione a Internet. – kinORnirvana

2

Questo codice è contenuto in una classe di test jUnit che utilizzo per verificare se è disponibile una connessione. Ricevo sempre una connessione, ma se si controlla la lunghezza del contenuto dovrebbe essere -1 se non nota:

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(); 
    } 
3

Il codice utilizzando NetworkInterface aspettare che la rete ha funzionato per me fino a quando ho passato da indirizzo di rete fissa a DHCP . Un lieve miglioramento rende il lavoro anche con 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; 
      } 
    } 
} 

Questo funziona per Java 7 in openSUSE 13.1 per la rete IPv4. Il problema con il codice originale è che sebbene l'interfaccia fosse attiva dopo la ripresa dalla sospensione, non è stato ancora assegnato un indirizzo di rete IPv4. Dopo aver atteso questo incarico, il programma può connettersi ai server. Ma non ho idea di cosa fare in caso di IPv6.

17

Il codice fornito in pratica e una chiamata allo connect dovrebbero essere sufficienti. Quindi sì, potrebbe essere che Google non sia disponibile, ma qualche altro sito che devi contattare è attivo, ma quanto è probabile? Inoltre, questo codice dovrebbe essere eseguito solo quando effettivamente non si riesce ad accedere alla risorsa esterna (in un blocco catch per cercare di capire quale fosse la causa dell'errore), quindi direi che se entrambe le risorse esterne di interesse sono e Google non è disponibile è probabile che tu abbia un problema di connettività netta.

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

Questo funziona, ma richiede un po 'di tempo finché non restituisce 'false'. Qualunque soluzione più veloce? 'Cmd' mi dice immediatamente che non è stato possibile trovare l'host quando provo a eseguire il ping. – BullyWiiPlaza

+0

Per qualche motivo questo non funziona su iOS. – WirJun

1
public boolean checkIntConnection() 
    { 
     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) 
     { 

     } 
     finally 
     { 
      try 
      { 
       sock.close(); 
      } 
      catch(Exception e) 
      { 

      } 
     } 

     return status; 
    } 
3

Questo codice dovrebbe fare il lavoro in modo affidabile.

Si noti che quando si utilizza la dichiarazione try-with-resources non è necessario chiudere le risorse.

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; 
     } 
    } 
} 
1

InetAddress.isReachable a volte restituire false se esiste una connessione Internet.

Un metodo alternativo per verificare la disponibilità di Internet in java è: Questa funzione effettua un ping reale 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; 
     } 
} 
+0

Risposta molto buona – GOXR3PLUS

0

C'è anche un'opzione di Gradle --offline che forse provoca il comportamento desiderato.

+0

Questo non sembra correlato alla domanda. – mkobit

Problemi correlati