Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/189.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Android中检查主机可达性/可用性_Android - Fatal编程技术网

在Android中检查主机可达性/可用性

在Android中检查主机可达性/可用性,android,Android,在我的应用程序互联网创业之初,我一直在尝试做一个简单的主机可达性测试,但文档没有帮助,在不同的地方也找不到示例,我尝试了许多解决方案,但都没有成功,所以,如果有人能给我指出一个明确的方法,用android来检查主机的可用性,那真是太棒了,只要在可以访问主机的情况下将bool切换为true就行了 如果API8对此过程有很大影响,则im将使用API8,并且必须满足非根设备的需要,以便inetaddress.isRecable退出检查连接,您可以使用: public boolean isOnline(

在我的应用程序互联网创业之初,我一直在尝试做一个简单的主机可达性测试,但文档没有帮助,在不同的地方也找不到示例,我尝试了许多解决方案,但都没有成功,所以,如果有人能给我指出一个明确的方法,用android来检查主机的可用性,那真是太棒了,只要在可以访问主机的情况下将bool切换为true就行了


如果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
}