【问题标题】:Android: How to check if the server is available?Android:如何检查服务器是否可用?
【发布时间】:2009-09-18 08:10:00
【问题描述】:

我正在开发一个连接到服务器的应用程序。如果服务器可用,现在登录和数据传输工作正常。当服务器不可用时,就会出现问题。在这种情况下,该方法发送登录请求并等待响应。

有谁知道如何检查服务器是否可用(可见)?

需要实现的简单逻辑的伪代码如下:

  1. String serverAddress = (从配置文件中读取值) //已经完成
  2. boolean serverAvailable = (检查服务器serverAddress是否可用)//必须实现
  3. (这里是依赖于serverAvailable的逻辑)

【问题讨论】:

标签: android networking connectivity


【解决方案1】:

他可能需要 Java 代码,因为他在 Android 上工作。 Java 等价物——我相信它适用于 Android——应该是:

InetAddress.getByName(host).isReachable(timeOut)

【讨论】:

  • 请注意,这并不总是有效! From the docs:“此方法首先尝试使用 ICMP(ICMP ECHO REQUEST)。当第一步失败时,将在远程主机的端口 7(Echo)上建立 TCP 连接。”我发现许多 Android 设备不支持 ICMP,并且许多服务器不接受端口 7 上的 TCP 连接。isReachable() 然后在服务器可访问时简单地超时。
  • 在主线程中使用也需要异步使用
【解决方案2】:

通过一个简单的类似 ping 的测试,这对我有用:

static public boolean isURLReachable(Context context) {
    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo netInfo = cm.getActiveNetworkInfo();
    if (netInfo != null && netInfo.isConnected()) {
        try {
            URL url = new URL("http://192.168.1.13");   // Change to "http://google.com" for www  test.
            HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
            urlc.setConnectTimeout(10 * 1000);          // 10 s.
            urlc.connect();
            if (urlc.getResponseCode() == 200) {        // 200 = "OK" code (http connection is fine).
                Log.wtf("Connection", "Success !");
                return true;
            } else {
                return false;
            }
        } catch (MalformedURLException e1) {
            return false;
        } catch (IOException e) {
            return false;
        }
    }
    return false;
}

不要忘记在线程中运行这个函数(而不是在主线程中)。

【讨论】:

  • 抱歉,我还在寻找解决方案。我发现在后台运行它会消耗大量带宽,因为我想它会在后台下载 while 页面。所以现在尝试使用 ping 进程。
  • 好的,我明白了,感谢您提供的详细信息。随意编辑我的答案,或提供您自己的答案;)
  • @Gauthier Boaglio :我尝试使用 ping 但它的返回结果为 2 没有任何成功。我发表的评论可能会误导其他人,因此现在将其删除。谢谢你的时间:)
  • 权限在哪里?你是在什么地方写的吗……?
【解决方案3】:

你可以使用

InetAddress.getByName(host).isReachable(timeOut)

但是当主机没有在 tcp 7 上应答时它不能正常工作。您可以借助此功能检查该端口上的主机是否可用:

public static boolean isHostReachable(String serverAddress, int serverTCPport, int timeoutMS){
    boolean connected = false;
    Socket socket;
    try {
        socket = new Socket();
        SocketAddress socketAddress = new InetSocketAddress(serverAddress, serverTCPport);
        socket.connect(socketAddress, timeoutMS);
        if (socket.isConnected()) {
            connected = true;
            socket.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        socket = null;
    }
    return connected;
}

【讨论】:

    【解决方案4】:
    public static boolean IsReachable(Context context) {
        // First, check we have any sort of connectivity
        final ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        final NetworkInfo netInfo = connMgr.getActiveNetworkInfo();
        boolean isReachable = false;
    
        if (netInfo != null && netInfo.isConnected()) {
            // Some sort of connection is open, check if server is reachable
            try {
                URL url = new URL("http://www.google.com");
                //URL url = new URL("http://10.0.2.2");
                HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
                urlc.setRequestProperty("User-Agent", "Android Application");
                urlc.setRequestProperty("Connection", "close");
                urlc.setConnectTimeout(10 * 1000);
                urlc.connect();
                isReachable = (urlc.getResponseCode() == 200);
            } catch (IOException e) {
                //Log.e(TAG, e.getMessage());
            }
        }
    
        return isReachable;
    }
    

    试试吧,为我工作,不要忘记激活的 android.permission.ACCESS_NETWORK_STATE

    【讨论】:

    • 请检查您的连接或检查服务器连接
    【解决方案5】:

    您正在使用 HTTP 吗?然后,您可以在 HTTP 连接上设置超时,如下所示:

    private void setupHttpClient() {
        BasicHttpParams httpParams = new BasicHttpParams();
    
        ConnManagerParams.setTimeout(httpParams, CONNECTION_TIMEOUT);
        //...
    
        ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(
                httpParams, schemeRegistry);
        this.httpClient = new DefaultHttpClient(cm, httpParams);
    }
    

    如果您随后执行请求,您将在给定超时后收到异常。

    【讨论】:

      【解决方案6】:
      public boolean isConnectedToServer(String url, int timeout) {
      try{
          URL myUrl = new URL(url);
          URLConnection connection = myUrl.openConnection();
          connection.setConnectTimeout(timeout);
          connection.connect();
          return true;
      } catch (Exception e) {
          // Handle your exceptions
          return false;
       }
      }
      

      【讨论】:

        【解决方案7】:

        哦,不,不,Java 中的代码不起作用:InetAddress.getByName("fr.yahoo.com").isReachable(200) 虽然在 LogCat 中我看到了它的 IP 地址(与 20000 ms 相同)超时)。

        看来使用'ping'命令比较方便,例如:

        运行时运行时 = Runtime.getRuntime(); 进程 proc = runtime.exec("ping fr.yahoo.com -c 1"); // 其他服务器,例如 proc.waitFor(); int exit = proc.exitValue(); if (exit == 0) { // 正常退出 /* 获取执行 ping 命令的输出内容并解析 * 判断服务器是否可达 */ } else { // 异常退出,所以判断服务器不可达 ... }

        【讨论】:

        • 看到这被标记为 Android,我想节省任何人尝试这个的努力,因为在 Linux 上打开原始套接字需要 root 权限。因此,它不会在大多数无根设备上运行。我发现它可以在几个 HTC 设备上工作,但其他设备只是返回“ping: icmp open socket: Operation not allowed”。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-03
        • 2016-05-19
        • 2014-11-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多