Как проверить наличие интернет-соединения в java?

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Этот код:

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

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

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


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

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

Обратите внимание: при использовании инструкции 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. Сначала я вижу, могу ли я разрешить доменное имя на IP-адрес.
  2. Затем я пытаюсь подключиться через TCP (порт 80 и / или 443) и закрыть изящно.
  3. Наконец, я вышлю HTTP-запрос и проведу ответ на 200 ответов.

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

 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 означает, что интернет-соединение не установлено. 🙂

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

 Enumeration interfaces = NetworkInterface.getNetworkInterfaces(); while (interfaces.hasMoreElements()) { NetworkInterface interf = interfaces.nextElement(); if (interf.isUp() && !interf.isLoopback()) { List adrs = interf.getInterfaceAddresses(); for (Iterator 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.

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

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

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

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

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

 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"); } } } 
  • Как изменить параметры сети (IP-адрес, DNS, WINS, имя хоста) с кодом в C #
  • Как рассчитать количество параметров для сверточной нейронной сети?
  • Предельная точка?
  • Давайте будем гением компьютера.