29

我在表单中有一个 URL

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

并想检查它是否可用。

如果我尝试使用浏览器打开这些链接,这些链接会将我重定向到错误的请求页面,但是通过代码我可以获得所需的数据。

在 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)如果服务器返回一些数据但在完成请求之前中断了请求,超时将被忽略并卡住,直到返回Exception导致执行到达 catch 块,这是此方法缓慢的原因,但我仍然没有t 找到了避免这种情况的有效解决方案。

b)如果我启动 android 设备并在没有连接的情况下打开应用程序,则正确返回 false 值,如果应用程序在 Internet 连接处于活动状态的情况下打开并且设备失去其 Internet 连接,则与案例 A 发生相同的事情(如果我尝试终止并重新启动应用程序...我不知道为什么,我想有些东西仍然被缓存)

所有这些似乎都与Java URLConnection 在读取时没有提供故障安全超时的事实有关。查看此链接上的示例,我看到它使用线程以某种方式中断连接,但是如果我new Thread(new InterruptThread(Thread.currentThread(), con)).start();像示例中那样简单地添加行,则没有任何变化。

4

8 回答 8

30
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;
}
于 2014-09-17T10:04:13.930 回答
7
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;
        }
    }
于 2014-09-12T12:51:28.047 回答
1

您是否尝试过使用原始套接字?

它应该运行得更快,因为它位于较低层

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;
}
于 2014-09-17T06:44:31.257 回答
0

正如'eridal'所提到的,应该更快,打开套接字;但是,它只告诉您服务器正在侦听主机和端口,但可以肯定的是,您需要编写 HTTP 或错误请求(垃圾),您应该得到 HTTP/1.1 400 Bad Request。通过读取返回的第一行,如果它包含 HTTP,那么您可以确定服务器是 HTTP 服务器。这样您就可以确定服务器和 HTTP 服务器一样可用。

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

于 2014-09-17T10:18:00.287 回答
0

上个月我遇到了类似的问题,有人帮我举了一个可选的例子。我想给你同样的建议

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 服务器可用,否则当前不可用。

于 2014-09-19T05:55:04.800 回答
0

下面的代码等到网页可用:

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);
        }
    }
于 2016-01-07T08:17:04.780 回答
0

在这里,作者建议:

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 我自己的页面,我还是想请求它?当然!如果您想区分“可用的互联网连接”和您自己的服务器是否可访问,您甚至可以同时检查两者

阅读链接。它看起来很好

编辑:在我使用它的经验中,它不如这种方法快:

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

它们有点不同,但在仅检查互联网连接的功能中,由于连接变量,第一种方法可能会变慢。

于 2017-08-29T12:41:27.967 回答
-1
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();
                        }
于 2014-09-22T06:48:56.530 回答