检查Android中的主机可访问性/可用性

我一直试图做我认为在我的应用程序互联网企业开始时主机测试的简单可达性,但文档没有帮助,也没有在各个地方find的例子,我尝试了许多解决方案没有运气,所以如果有人可以指向一个确定的方法来检查主机可用性与android是非常棒的,如果可以到达主机,只需要将bool切换为true

我使用API​​8,如果这对这个过程有很大的不同,并且必须迎合非root设备,所以inetaddress.isReachable已经出来了

这不是很漂亮,但这就是我做到的:

boolean exists = false; try { SocketAddress sockaddr = new InetSocketAddress(ip, port); // Create an unbound socket Socket sock = new Socket(); // This method will block no more than timeoutMs. // If the timeout occurs, SocketTimeoutException is thrown. int timeoutMs = 2000; // 2 seconds sock.connect(sockaddr, timeoutMs); exists = true; } catch(IOException e) { // Handle exception } 

要检查连接,您可以使用:

 public boolean isOnline(Context context) { ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo netInfo = cm.getActiveNetworkInfo(); return netInfo != null && netInfo.isConnectedOrConnecting(); } 

如果它报告了连接,您还可以通过尝试执行http访问地址然后检查返回的状态代码进行检查。 如果没有返回状态代码,则可以肯定主机无法访问。

Java 7及以上版本

这是我用于任何Java 7及以上项目的代码:

 /** * Check if host is reachable. * @param host The host to check for availability. Can either be a machine name, such as "google.com", * or a textual representation of its IP address, such as "8.8.8.8". * @param port The port number. * @param timeout The timeout in milliseconds. * @return True if the host is reachable. False otherwise. */ public static boolean isHostAvailable(final String host, final int port, final int timeout) { try (final Socket socket = new Socket()) { final InetAddress inetAddress = InetAddress.getByName(host); final InetSocketAddress inetSocketAddress = new InetSocketAddress(inetAddress, port); socket.connect(inetSocketAddress, timeout); return true; } catch (java.io.IOException e) { e.printStackTrace(); return false; } } 

另一种选择(更快但更不精确)

您可以使用inetAddress.isReachable(int timeout)而不是打开完整的套接字连接。 这会使检查更快但也更不精确,因为这种方法只是建立在一个echo请求上:

如果可以获得特权,则典型的实现将使用ICMP ECHO REQUEST,否则它将尝试在目标主机的端口7(Echo)上建立TCP连接。

对于我的用例,我必须建立与Web服务器的连接。 因此,我必须启动并运行服务器上的服务。 因此,对于简单的echo请求,套接字连接是我的首选。

Java 7以下

上面代码中的try-catch-resource块仅适用于Java 7和更新版本。 在版本7之前,需要finally -block以确保正确关闭资源:

 final Socket socket = new Socket(); try { ... } catch (java.io.IOException e) { ... } finally { if (socket != null) { socket.close(); // this will throw another exception... just let the function throw it } } 

用法

host可以是计算机名称,例如“google.com”,也可以是IP地址,例如“8.8.8.8”。

 if (isHostAvailable("google.com", 80, 1000)) { // do you work here } 

进一步阅读

Android文档:

  • sockets
  • 如果InetSocketAddress
  • InetAddress.getByName()
  • InetAddress.isReachable()

堆栈溢出:

  • 用于ping HTTP URL以获取可用性的首选Java方法

试试这个:

 boolean reachable = false; try { reachable = InetAddress.getByName("www.example.com").isReachable(2000); } catch (IOException e) { e.printStackTrace(); reachable = false; } if (reachable) { // do your work here } 

但是,即使Web服务器运行正常,因为isReachable(int timeout)的实现方式,这可能会失败:

测试该地址是否可达。 尽管尝试到达主机,但是防火墙和服务器配置可以阻止导致无法访问状态的请求,同时可以访问某些特定端口。 如果可以获得特权,则典型的实现将使用ICMP ECHO REQUEST,否则它将尝试在目标主机的端口7(Echo)上建立TCP连接。