如何快速检查URL服务器是否可用

我在表单中有一个URL

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

并想检查它是否可用。

如果我尝试用浏览器打开这些链接,链接会将我redirect到一个错误的请求页面,但是通过代码我可以获取我需要的数据。

在HTTP请求过程中使用try-catch块非常慢,所以我想知道如何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)如果服务器返回一些数据,但在完成请求之前中断请求,超时将被忽略并卡住,直到返回一个导致执行到达catch块的Exception ,这是此方法缓慢的原因,而且我还没有找不到有效的解决scheme来避免这种情况。

b)如果我启动android设备,并打开应用程序没有连接,错误的价值是正确返回,如果应用程序打开与互联网连接活跃,设备失去了互联网连接发生的情况下同样的事情A(也如果我尝试终止并重新启动应用程序…我不知道为什么,我想这东西仍然caching)

所有这些似乎都与Java URLConnection在读取时不提供故障安全超时有关。 看这个链接的示例我已经看到,使用线程中断连接以某种方式,但如果我只是添加线new Thread(new InterruptThread(Thread.currentThread(), con)).start(); 像样本中没有任何变化。

Solutions Collecting From Web of "如何快速检查URL服务器是否可用"

 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”所提到的那样,应该更快,打开socket; 然而,它只会告诉你一台服务器正在监听主机和端口,但是可以肯定的是,你需要写入HTTP或者一个错误的请求(垃圾),你应该得到HTTP / 1.1 400 Bad Request。 通过读取返回的第一行,如果它包含HTTP,那么你确定服务器是一个HTTP服务器。 这样你就可以确定服务器和HTTP服务器一样可用。

这是eridal对上述答案的扩展。

试试这个代码

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

这里作者提出这样的build议:

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

难道我不能只是ping我自己的网页,我想要求吗?当然! 你甚至可以检查两者,如果你想区分“可用的互联网连接”和你自己的服务器可达

阅读链接。 它看起来非常好

编辑:在我的使用它的exp,它不像这个方法一样快:

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

他们有点不同,但在检查连接到互联网的function,第一种方法可能会变慢由于连接variables。

上个月我有类似的问题,有人帮我一个可选的例子。 我想build议你一样

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

如果返回true,则表示您的url服务器可用,否则当前不可用。

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