Как проверить, есть ли интернет-соединение в Java? - PullRequest
56 голосов
/ 10 сентября 2009

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

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

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

Ответы [ 15 ]

46 голосов
/ 10 сентября 2009

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

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

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

20 голосов
/ 08 апреля 2014

Код, который вы в основном предоставили, плюс вызов 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;
    }
}
17 голосов
/ 10 сентября 2009

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

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

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

Фундаментальная проблема заключается в том, что вопрос «можно подключиться к Интернету» является плохо определенным вопросом, и без него сложно проверить:

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

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

7 голосов
/ 12 декабря 2012

Этот код:

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

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

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


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

7 голосов
/ 06 декабря 2009

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

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

Сам еще не пробовал.

6 голосов
/ 13 июня 2015

Этот код должен выполнять работу надежно.

Обратите внимание, что при использовании оператора 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;
        }
    }
}
4 голосов
/ 03 июня 2016

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

Альтернативный метод проверки доступности интернета в java: эта функция создает настоящий 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 голосов
/ 15 декабря 2013

Код, использующий 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.

4 голосов
/ 19 апреля 2010

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

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

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

4 голосов
/ 19 апреля 2010
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 означает, что подключение к Интернету не установлено. : -)

...