Как быстро проверить, доступен ли сервер URL-адресов

У меня есть URL-адрес в форме

http://www.mywebsite.com/util/conv?a=1&from=%s&to=%s 

И хотите проверить, доступно ли это.

Ссылки перенаправляют меня на страницу с плохим запросом, если я попытаюсь открыть их с помощью браузера, однако через код я могу получить нужные мне данные.

Использование блока try-catch в процедуре HTTP-запроса выполняется довольно медленно, поэтому мне интересно, как я могу выполнить ping-адрес, чтобы проверить, активен ли его сервер.


я пытался

 boolean reachable = InetAddress.getByName(myLink).isReachable(6000); 

Но возврат всегда false .

Я также пробовал

 public static boolean exists(String URLName) { try { HttpURLConnection.setFollowRedirects(false); HttpURLConnection con = (HttpURLConnection) new URL(URLName).openConnection(); con.setConnectTimeout(1000); con.setReadTimeout(1000); con.setRequestMethod("HEAD"); return (con.getResponseCode() == HttpURLConnection.HTTP_OK); } catch (Exception e) { e.printStackTrace(); return false; } } 

Это возвращает правильное значение в конце процесса, бит слишком медленный, если сервер недоступен.

РЕДАКТИРОВАТЬ

Я понял, в чем причина медленности

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

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

Все это, похоже, связано с тем, что Java URLConnection не обеспечивает отказоустойчивого таймаута при чтении. Глядя на образец по этой ссылке, я видел, что использует stream, чтобы каким-то образом прервать соединение, но если я просто добавлю строку new Thread(new InterruptThread(Thread.currentThread(), con)).start(); как в образце ничего не меняется.

 static public boolean isServerReachable(Context context) { ConnectivityManager connMan = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo netInfo = connMan.getActiveNetworkInfo(); if (netInfo != null && netInfo.isConnected()) { try { URL urlServer = new URL("your server url"); HttpURLConnection urlConn = (HttpURLConnection) urlServer.openConnection(); urlConn.setConnectTimeout(3000); //<- 3Seconds Timeout urlConn.connect(); if (urlConn.getResponseCode() == 200) { return true; } else { return false; } } catch (MalformedURLException e1) { return false; } catch (IOException e) { return false; } } return false; } 

или используя время выполнения:

 Runtime runtime = Runtime.getRuntime(); Process proc = runtime.exec("ping www.serverURL.com"); //<- Try ping -c 1 www.serverURL.com int mPingResult = proc .waitFor(); if(mPingResult == 0){ return true; }else{ return false; } 

Вы можете попробовать isReachable() но для него есть ошибка, и в этом комментарии говорится, что isReachable () требует разрешения root :

 try { InetAddress.getByName("your server url").isReachable(2000); //Replace with your name return true; } catch (Exception e) { return false; } 
 public static boolean exists(String URLName) { try { HttpURLConnection.setFollowRedirects(false); // note : you may also need // HttpURLConnection.setInstanceFollowRedirects(false) HttpURLConnection con = (HttpURLConnection) new URL(URLName) .openConnection(); con.setRequestMethod("HEAD"); return (con.getResponseCode() == HttpURLConnection.HTTP_OK); } catch (Exception e) { e.printStackTrace(); return false; } } 

вы пытались использовать сырые сокеты?

Он должен работать быстрее, так как он находится на нижнем уровне

 static boolean exists(String serverUrl) { final Socket socket; try { URL url = new URL(serverUrl); socket = new Socket(url.getHost(), url.getPort()); } catch (IOException e) { return false; } try { socket.close(); } catch (IOException e) { // will never happen, it's thread-safe } return true; } 

Как упоминалось «eridal», это должно быть быстрее, откройте сокет; однако он сообщает только, что сервер прослушивает хост и порт, но, конечно, вам нужно написать HTTP или, альтернативно, плохой запрос (хлам), вы должны получить HTTP / 1.1 400 Bad Request. Прочитав первую строку, если она содержит HTTP, вы уверены, что сервер является HTTP-сервером. Таким образом, вы уверены, что сервер доступен, а также HTTP-сервер.

Это в дополнение к вышеуказанному ответу eridal.

У меня была аналогичная проблема в прошлом месяце, и кто-то помог мне с дополнительным примером. Я хотел бы предложить вам то же самое

 public boolean isServerReachable() // To check if server is reachable { try { InetAddress.getByName("google.com").isReachable(3000); //Replace with your name return true; } catch (Exception e) { return false; } } 

если return true, чем доступен ваш сервер url, в настоящее время недоступно.

Попробуйте этот код

 public boolean isServerAlive() // To check if server is reachable { try { InetAddress.getByName("google.com").isReachable(3000); //Replace with your name return true; } catch (Exception e) { return false; } } 

Ниже кода пока не будет доступна веб-страница:

 public void waitForWebavailability() throws Exception { boolean success = false; long waitTime = 0; while (!success) { try { waitTest(30000); waitTime += 30000; if (waitTime > 600000) { System.out.println("Web page is not available"); } webDriver.get("http://www.google.com"); if (webDriver.getTitle().toLowerCase().contains("sometitle")) { success = true; } } catch (Exception e) { success = false; } } } // Code related to waittest public void waitTest(long millis) throws Exception { try { Thread.sleep(millis); } catch (InterruptedException e) { throw new Exception(e); } } 

здесь автор предлагает это:

 public boolean isOnline() { Runtime runtime = Runtime.getRuntime(); try { Process ipProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8"); int exitValue = ipProcess.waitFor(); return (exitValue == 0); } catch (IOException | InterruptedException e) { e.printStackTrace(); } return false; } 

Не могу ли я просто пинговать свою страницу, которую я хочу запросить в любом случае? Конечно! Вы даже можете проверить оба варианта, если вы хотите различать «доступное интернет-соединение» и ваши собственные серверы, доступные

прочитайте ссылку. его кажется очень хорошим

EDIT: в моем опыте использования, это не так быстро, как этот метод:

 public boolean isOnline() { NetworkInfo netInfo = connectivityManager.getActiveNetworkInfo(); return netInfo != null && netInfo.isConnectedOrConnecting(); } 

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

 if (android.os.Build.VERSION.SDK_INT > 9) { StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder() .permitAll().build(); StrictMode.setThreadPolicy(policy); } try { URL diachi = new URL("http://example.com"); HttpURLConnection huc = (HttpURLConnection) diachi.openConnection(); huc.setRequestMethod("HEAD"); int responseCode = huc.getResponseCode(); if (responseCode != 404) { //URL Exist } else { //URL not Exist } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }