在Android中检查主机可达性/可用性
在我的应用程序互联网创业之初,我一直在尝试做一个简单的主机可达性测试,但文档没有帮助,在不同的地方也找不到示例,我尝试了许多解决方案,但都没有成功,所以,如果有人能给我指出一个明确的方法,用android来检查主机的可用性,那真是太棒了,只要在可以访问主机的情况下将bool切换为true就行了在Android中检查主机可达性/可用性,android,Android,在我的应用程序互联网创业之初,我一直在尝试做一个简单的主机可达性测试,但文档没有帮助,在不同的地方也找不到示例,我尝试了许多解决方案,但都没有成功,所以,如果有人能给我指出一个明确的方法,用android来检查主机的可用性,那真是太棒了,只要在可以访问主机的情况下将bool切换为true就行了 如果API8对此过程有很大影响,则im将使用API8,并且必须满足非根设备的需要,以便inetaddress.isRecable退出检查连接,您可以使用: public boolean isOnline(
如果API8对此过程有很大影响,则im将使用API8,并且必须满足非根设备的需要,以便inetaddress.isRecable退出检查连接,您可以使用:
public boolean isOnline(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
return netInfo != null && netInfo.isConnectedOrConnecting();
}
如果它报告了连接,您还可以通过尝试对地址执行http get,然后检查返回的状态代码来进行检查。如果没有返回状态码,则可以确定主机无法访问。这不太好,但我就是这样做的:
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
}
试试这个:
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服务器正常启动并运行,这也可能失败:
测试该地址是否可访问。尽最大努力是由
实现尝试到达主机,但防火墙和服务器
配置可能会阻止导致无法访问状态的请求
而某些特定端口可能是可访问的。典型的实现
如果可以获得特权,将使用ICMP回显请求,
否则,它将尝试在端口7(Echo)上建立TCP连接
目标主机的名称
更快的解决方案
您可以使用它来代替打开一个完整的套接字连接。这将使检查更快,但也更不精确,因为此方法仅基于回显请求:
如果可以获得特权,典型的实现将使用ICMP ECHO请求,否则它将尝试在目标主机的端口7(ECHO)上建立TCP连接
对于我的用例,我必须建立到web服务器的连接。因此,我必须确保服务器上的服务已启动并正在运行。因此,与简单的回显请求相比,套接字连接是我的首选
标准溶液 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;
}
}
低于Java7
上面代码中的try-catch-resource
块仅适用于Java 7和更新版本。在版本7之前,最后需要一个块来确保资源正确关闭:
public static boolean isHostAvailable(final String host, final int port, final int timeout) {
final Socket socket = new Socket();
try {
... // same as above
} catch (java.io.IOException e) {
... // same as above
} 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”
进一步阅读
Android文档:
堆栈溢出:
如果我没有弄错,这只是检查设备是否有能力使用互联网,而不是检查实际主机/网站的可用性?是的,提供的代码确实检查了该能力,但随后您可以通过尝试在主机上执行http get来检查主机的可访问性。将我的代码片段与ghostbust555代码相结合将提供一个非常健壮的检查工作流。例如,如果我的代码显示有互联网连接,请运行他的代码。如果没有可用的internet连接,那么尝试联系主机是没有意义的。我想是的,谢谢,我已经在按照您所说的做了:)getActiveNetworkInfo可以检查的所有内容是设备是否有IP地址并且正在与网络通信。它不会检查并确保网络可以与Internet或您的服务器进行通信。此代码需要以下权限:android.permission.ACCESS\u network\u state使用各种uri并故意删除和禁用服务,经过完美测试,如果主机已启动并运行,它的id是否正确。是否应使用套接字对象使用后是否关闭?这取决于你想用它做什么。如果您只是检查ip是否存在,然后选择“是”将其关闭,如果您只是检查ip是否存在以便向其发送信息,则只需写入套接字。但是,如果您只是想知道主机是否已启动,则应尝试哪个端口?无法保证给定端口将打开(取决于设备)。也许我遗漏了一些东西,如果主机启动,它将必须至少有一个静态端口,它将始终拥有,或者您将无法连接到它,例如http的端口80。您可以检查多个端口,但如果您不确定其中一个端口是否处于活动状态,请务必注意,isReachable会尝试ICMP ping,然后尝试TCP echo(端口7)。这些通常在HTTP服务器上关闭。因此,如果ICMP和TCP端口7被过滤掉,那么在端口80上的web服务器上运行良好的API将被报告为无法访问!我不这么认为。事实上,这种回音服务在web服务器中很少关闭,这与“经常”相去甚远。事实上,没有一家大型网站关闭了它们,这样做是一种不好的做法,但这是另一种讨论。不幸的是,除非设备扎根,否则这在Android中不会起作用。请参见:您可以忽略对true的检查。只要写:if(reachable){…}
如果存在未处理的异常,它将如何在Android Studio中运行?我不太明白您的要求是什么?“未处理的异常”是什么意思?imho,下划线代码可能引发的所有异常都将被捕获。
if (isHostAvailable("google.com", 80, 1000)) {
// do you work here
}