Как проверить, есть ли интернет-соединение в Java?

Как вы можете проверить, можете ли вы подключиться к Интернету через java? Один из способов:

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

Но есть ли что-то более подходящее для выполнения этой задачи, особенно, если вам нужно делать последовательные проверки очень часто и потеря интернет-соединения весьма вероятна?

Ответ 1

Вам необходимо подключиться к месту, которое требуется вашему фактическому приложению. В противном случае вы проверяете, есть ли у вас соединение с чем-то неактуальным (в этом случае Google).

В частности, если вы пытаетесь поговорить с веб-сервисом, и если вы контролируете веб-сервис, было бы неплохо иметь какой-то дешевый метод "получить статус". Таким образом, у вас есть гораздо лучшее представление о том, может ли ваш "реальный" вызов работать.

В других случаях достаточно просто открыть соединение с портом, который должен быть открыт, или отправить пинг. InetAddress.isReachable вполне может быть подходящим API для ваших нужд здесь.

Ответ 2

Код, который вы в основном предоставили, плюс вызов для connect должен быть достаточным. Так что да, может быть, что Google не доступен, но какой-то другой сайт, с которым вам нужно связаться, но насколько это возможно? Кроме того, этот код должен выполняться только тогда, когда вы фактически не можете получить доступ к своему внешнему ресурсу (в блоке catch чтобы попытаться выяснить причину сбоя), поэтому я бы сказал, что если ваш внешний ресурс, представляющий интерес, и Google недоступно, у вас есть проблема с сетевым подключением.

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

Ответ 3

Люди предложили использовать INetAddress.isReachable. Проблема в том, что некоторые сайты настраивают свои брандмауэры для блокировки сообщений ICMP Ping. Таким образом, "ping" может выйти из строя, даже если веб-служба доступна.

И, конечно же, верно и обратное. Хост может отвечать на пинг, даже если веб-сервер не работает.

И, конечно, машина может быть неспособна напрямую подключиться к определенным (или всем) веб-серверам из-за ограничений локального брандмауэра.

Основная проблема заключается в том, что "можно подключиться к Интернету" - это нечеткий вопрос, и такого рода испытания трудно проверить:

  • информацию о пользовательской машине и локальной сети, а также
  • информацию о том, что приложение должно получить доступ.

Как правило, самым простым решением является приложение, чтобы просто попытаться получить доступ к тому, что ему нужно для доступа, и отпасть от человеческого интеллекта, чтобы выполнить диагноз.

Ответ 4

Если вы используете java 6, можете использовать NetworkInterface для проверки доступных сетевых интерфейсов. То есть что-то вроде этого:

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

Я еще не пробовал себя.

Ответ 5

Этот код:

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

Возвращает - мне - true если не в сети, и false, в противном случае. (ну, я не знаю, правда ли это для всех компьютеров).

Это работает намного быстрее, чем другие подходы, здесь.


РЕДАКТИРОВАТЬ: Я обнаружил, что это работает только в том случае, если выключен "флип-переключатель" (на ноутбуке) или какой-либо другой системный параметр для подключения к Интернету. То есть сама система знает, что не нужно искать никаких IP-адресов.

Ответ 6

Этот код должен сделать работу надежно.

Обратите внимание: при использовании инструкции try-with-resources нам не нужно закрывать ресурсы.

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

Ответ 7

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

Поместите вышеуказанные операторы в блоки try catch и, если исключение в catch означает, что интернет-соединение не установлено.: -)

Ответ 8

Я обычно разбиваю его на три шага.

  • Сначала я вижу, могу ли я разрешить доменное имя на IP-адрес.
  • Затем я пытаюсь подключиться через TCP (порт 80 и/или 443) и закрыть изящно.
  • Наконец, я вышлю HTTP-запрос и проверю ответ на 200.

Если сбой в какой-либо точке, я предоставляю пользователю соответствующее сообщение.

Ответ 9

Код, использующий NetworkInterface для ожидания работы сети, работал у меня, пока я не перешел с фиксированного сетевого адреса на DHCP. Небольшое усиление заставляет его работать и с 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;
            }
    }
}

Это работает для Java 7 в openSuse 13.1 для сети IPv4. Проблема с исходным кодом заключается в том, что, хотя интерфейс возобновился после приостановки, сетевой адрес IPv4 еще не был назначен. После ожидания этого задания программа может подключаться к серверам. Но я не знаю, что делать в случае IPv6.

Ответ 10

InetAddress.isReachable когда-нибудь вернет false, если существует интернет-соединение.

Альтернативный метод проверки доступности Интернета в java: Эта функция делает реальный ICMP ECHO ping.

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

Ответ 11

1) Выясните, к какому приложению нужно подключиться.

2) Настройте рабочий процесс, чтобы проверить InetAddress.isReachable, чтобы отслеживать подключение к этому адресу.

Ответ 12

Этот код содержится в классе тестирования jUnit, который я использую для проверки доступности соединения. Я всегда получаю соединение, но если вы проверяете длину содержимого, он должен быть -1, если не известен:

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

Ответ 13

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

Ответ 14

Существует также опция gradle --offline, которая может привести к поведению, которое вы хотите.

Ответ 15

Следующий фрагмент кода позволяет нам получить статус сети на нашем устройстве 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");
            }
        }
    }