Pergunta

Como você verificar se você pode se conectar à internet através de java? Uma forma seria:

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

Mas há algo mais apropriado para executar essa tarefa, especialmente se você precisa fazer verificações consecutivas muitas vezes e uma perda de conexão com a internet é altamente provável?

Foi útil?

Solução

Você deve ligar para o lugar que sua aplicação real precisa. Caso contrário, você está testando se você tem uma conexão com algum irrelevante (Google, neste caso).

Em particular, se você está tentando falar com um serviço web, e se você está no controle do serviço web, seria uma boa idéia para ter algum tipo de barata "obter o status" método web. Dessa forma você terá uma idéia melhor muito de saber se a sua chamada "real" é susceptível de trabalho.

Em outros casos, apenas abrindo uma conexão com uma porta que deve ser aberta pode ser suficiente - ou enviar um ping. InetAddress.isReachable pode muito bem ser uma API apropriado para suas necessidades aqui.

Outras dicas

O código que você basicamente fornecidos, além de uma chamada para connect deve ser suficiente. Então, sim, pode ser que apenas do Google não está disponível, mas algum outro site que você precisa para contato está ligado, mas a probabilidade é que? Além disso, este código só deve ser executado quando você realmente não conseguem acessar o recurso externo (em um bloco catch para tentar descobrir qual é a causa da falha foi), então eu diria que, se tanto o seu recurso externo de interesse e Google não são chances disponíveis são que você tem um problema de conectividade rede.

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

As pessoas têm sugerido usando INetAddress.isReachable. O problema é que alguns sites configurar seus firewalls para bloquear mensagens ICMP Ping. Assim, um "ping" pode falhar mesmo que o serviço web está acessível.

E, claro, o inverso também é verdadeiro. O hospedeiro pode responder a um ping mesmo que o servidor está em baixo.

E, claro, uma máquina pode não ser capaz de se conectar diretamente a certas (ou todos) servidores web devido a restrições de firewall local.

O problema fundamental é que "pode ??se conectar à internet" é uma questão mal definido, e este tipo de coisa é difícil de teste sem:

  1. informações sobre a máquina do usuário e "local" ambiente de rede e
  2. informações sobre o que as necessidades de aplicativos de acesso.

Assim, em geral, a solução mais simples é para um aplicativo para apenas tentar o acesso seja o que precisa de acesso, e cair para trás sobre a inteligência humana para fazer o diagnóstico.

Se você estiver em java 6 pode usar NetworkInterface para verificar a existência de interfaces de rede disponíveis. Ou seja, algo como isto:

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

não tentei isso sozinho, ainda.

Este código:

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

Retorna - para mim - true se offline e false, caso contrário. (Bem, eu não sei se isso é verdade para todos os computadores).

Isso funciona muito mais rápido do que as outras abordagens, até aqui.


EDIT: Eu encontrei isso só trabalhando, se o "switch flip-" (em um laptop), ou alguma outra opção definida pelo sistema, para a ligação à Internet, está fora. Isso é, o próprio sistema não sabe a olhar para todos os endereços IP.

Este código deve fazer o trabalho de forma confiável.

Observe que ao usar a declaração try-with-resources nós don' t necessidade de fechar os recursos.

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

Normalmente, eu dividi-la em três etapas.

  1. A primeira vez que ver se consigo resolver o nome de domínio para um endereço IP.
  2. Em seguida, tentar se conectar via TCP (porta 80 e / ou 443) e perto graciosamente.
  3. Finalmente, vou emitir uma solicitação HTTP e verificação para uma volta de 200 resposta.

Se ele falhar em qualquer ponto, eu forneço a mensagem de erro apropriada para o usuário.

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

Coloque as afirmações acima em blocos catch tentativa e se uma exceção em meio capturados que não há nenhuma conexão de internet estabelecido. : -)

O código usando NetworkInterface que esperar para a rede funcionou para mim até que eu mudei de endereço de rede fixa para DHCP. A melhoria ligeira torna também trabalham com 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;
            }
    }
}

Isso funciona para Java 7 no openSUSE 13.1 para a rede IPv4. O problema com o código original é que, embora a interface foi depois de saírem de suspensão, um endereço de rede IPv4 ainda não foi atribuído. Depois de esperar por esta atribuição, o programa pode se conectar a servidores. Mas eu não tenho idéia do que fazer em caso de IPv6.

InetAddress.isReachable algum retorno false se existir ligação à Internet.

Um método alternativo para verificar a disponibilidade internet em Java é:. Esta função faz um ping ICMP ECHO verdadeiro

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

1) descobrir onde suas necessidades de aplicação para se conectar a.

2) Estabelecer um processo de trabalho para verificar InetAddress.isReachable para monitorar a conexão para esse endereço.

Este código está contido dentro de uma classe de teste JUnit eu uso para testar se uma conexão está disponível. Eu sempre receber uma ligação, mas se você verificar o tamanho do conteúdo que deve ser -1 se não for conhecido:

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

Há também um --offline opção Gradle que talvez resulta no comportamento que você quer.

O seguinte pedaço de código nos permite obter o status da rede em nosso dispositivo 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");
            }
        }
    }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top