Как проверить, если подключение к интернету присутствует в Java?
Как проверить, можно ли подключиться к интернету через java? Один из способов будет:
final URL url = new URL("http://www.google.com");
final URLConnection conn = url.openConnection();
... if we got here, we should have net ...
но есть что-то более подходящее для выполнения этой задачи, особенно если вам нужно сделать последовательных проверок очень часто и потеря подключения к интернету весьма вероятна?
15 ответов:
вы должны подключиться к месту, что ваше фактическое приложение нуждается. В противном случае вы проверяете, есть ли у вас соединение с чем-то нерелевантным (в данном случае 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. Так что "пинг" может завершиться неудачей, даже если веб-служба доступна.
и, конечно, верно и обратное. Хост может ответить на пинг, даже если веб-сервер не работает.
и конечно, машина может быть подключаются непосредственно к определенным (или всем) веб-сервера из-за локального брандмауэра ограничения.
основная проблема заключается в том, что "может подключиться к интернету" является неопределенным вопросом, и такого рода вещи трудно проверить без:
- информация о машине пользователя и "локальной" сетевой среде, а также
- информация о том, что приложение должно получить доступ.
таким образом, как правило, самое простое решение-это приложение, которое просто пытается получить доступ к тому, что ему нужно, и вернуться к человеку интеллект, чтобы сделать диагноз.
Если вы находитесь на java 6 можно использовать NetworkInterface чтобы проверить наличие доступных сетевых интерфейсов. То есть что-то вроде этого:
Enumeration<NetworkInterface> 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; } } }
Я обычно разбиваю его на три шага.
- сначала я посмотрю, могу ли я разрешить доменное имя на IP-адрес.
- затем я пытаюсь подключиться через TCP (порт 80 и/или 443) и корректно закрыть.
- наконец, я выдам 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, и если исключение в caught означает, что нет подключения к интернету. : -)
код, использующий 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.
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; } }
1)выясните, где ваше приложение должно быть подключено.
2) настройка рабочего процесса для проверки InetAddress.isReachable для мониторинга соединения с этим адресом.
этот код содержится в тестовом классе 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; }
следующий фрагмент кода позволяет нам получить статус сети на нашем устройстве 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"); } } }