2009-09-09 3 views
52

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

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

+20

Да, но этот «дубликат» принял answere, который даже не является решением, поэтому PLS не беспокоит – Chris

+0

Ответ на этот вопрос аналогичен мами другим вопросам той же формы. Единственный правильный способ определить, доступен ли какой-либо ресурс, - попытаться использовать его в обычном ходе выполнения и справиться с отказом как и когда это произойдет. Любая другая техника - это одна из форм попытки предсказать будущее. – EJP

ответ

44

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

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

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

+3

Ссылка на isReachable попала в неправильный класс. На странице http://java.sun.com/javase/6/docs/api/java/net/InetAddress.html#isReachable –

+12

что делать, если вы подключаетесь к ресурсу, с которым хотите общаться, и он не работает. как вы знаете, что проблема с целевым сервером, а не с bcs, не было интернет-соединения? поэтому «подключитесь к месту, в котором нуждается ваше фактическое приложение», на самом деле не является решением, которое не было бы надежной проверкой. – Chris

+4

@ Крис: Это зависит от того, действительно ли вы заботитесь о том, в чем проблема. Я согласен с тем, что вы можете получить больше диагностической информации, если (после сбоя) вы затем подключаетесь и в другом месте. Но самая важная часть информации, безусловно, «Могу ли я использовать ресурс, который я пытаюсь использовать?» –

2

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

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

+0

рабочий процесс? –

17

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

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

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

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

  1. информации о компьютере пользователя и «локальных» сети и
  2. информация о том, к чему приложение должно получить доступ.

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

+0

хорошо, не плохой определено. вопрос просто "есть интернет" не более. – Chris

+2

Это моя точка зрения. Вопрос «есть интернет» не определен. Прочтите текст выше для примеров, которые предназначены для иллюстрации этого. –

+0

@ Крис: «Интернет» не определен. Например, возможность попасть в Google не означает, что вы можете, например, добраться куда угодно. (Представьте, что DNS-сервер выключен, но в вашем файле hosts есть запись DNS.) –

6

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

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

Не пробовал сам.

+1

это только проверяет, включен ли интерфейс. Он не проверяет подключение к Интернету. – siamii

+0

Тем не менее, сетевой интерфейс, являющийся up, является необходимым условием для подключения к Интернету. Я думаю, что это имеет смысл в качестве первого шага более надежного решения. Это позволяет вам хотя бы увидеть, есть ли у вас активный сетевой интерфейс, не отправляя никакого сетевого трафика вообще. – adamfisk

+0

Это не то, о чем попросил ОП. – 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(); 

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

4

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

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

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

+0

Я думаю, что это может быть хорошим ответом, но вы можете подробно остановиться на нем, потому что сейчас это не очень хороший ответ. – Pacerier

6

Этот код:

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

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

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


EDIT: Я нашел это работает только, если «флип-переключатель» (на ноутбуке), или какая-либо другая система определяется вариантом, для подключения к Интернету, выключено. Это значит, что сама система не знает никаких IP-адресов.

+0

не работает для «127.0.0.1», но показывает ответ на другой доступный IP-адрес –

+0

Работает для меня, и мне это нравится и используется. Это своего рода предварительная проверка. Предварительная проверка для подключения сетевого интерфейса, который вы можете вызвать перед проверкой подключения к Интернету. – kinORnirvana

2

Этот код содержится в классе тестирования 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(); 
    } 
3

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

17

Код, который вам предоставили в основном, плюс звонок 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(); 
     return true; 
    } catch (MalformedURLException e) { 
     throw new RuntimeException(e); 
    } catch (IOException e) { 
     return false; 
    } 
} 
+0

Это работает, но требуется некоторое время, пока оно не вернет 'false'. Любое более быстрое решение? 'Cmd' сразу сообщает мне, что хост не может быть найден, когда я пытаюсь его выполнить. – BullyWiiPlaza

+0

По какой-то причине это не работает на 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

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

Обратите внимание, что при использовании инструкции 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; 
     } 
    } 
} 
1

InetAddress.isReachable когда-нибудь вернуться ложным, если подключение к Интернету существует.

Альтернативный способ проверки доступности интернета в 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; 
     } 
} 
+0

Очень хороший ответ – GOXR3PLUS

0

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

+0

Это не похоже на вопрос. – mkobit

Смежные вопросы