我有一个表单的URL
http://www.mywebsite.com/util/conv?a=1&from=%s&to=%s
并且想检查它是否可用.
如果我尝试使用浏览器打开这些链接,链接将重定向到一个不好的请求页面,但是通过代码,我可以获取我需要的数据.
在HTTP请求过程中使用try-catch块是相当缓慢的,所以我想知道如何ping一个类似的地址来检查它的服务器是否活动.
我努力了
boolean reachable = InetAddress.getByName(myLink).isReachable(6000);
但返回总是假的.
我也试过
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块的异常,这是造成此方法缓慢的原因,而且我仍然避开没有找到一个有效的解决方案来避免这种情况.
b)如果我启动Android设备并打开没有连接的应用程序,则false值将正确返回,如果应用程序打开,Internet连接处于活动状态,并且设备丢失其Internet连接发生在与A情况相同的情况(也如果我尝试终止并重新启动应用程序…我不知道为什么,我想有些东西仍然缓存)
所有这一切似乎与Java URLConnection在读取时不提供故障安全超时的事实有关.看看this link的样本,我看到使用线程以某种方式中断连接,但如果我添加一行新线程(新的InterruptThread(Thread.currentThread(),con)).start();像在样品中没有变化.
解决方法
static public boolean isServerReachable(Context context) { ConnectivityManager connMan = (ConnectivityManager) 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(),但是有一个bug filed for it和this comment says that isReachable() requires root permission:
try { InetAddress.getByName("your server url").isReachable(2000); //Replace with your name return true; } catch (Exception e) { return false; }