【问题标题】:Ping Application in AndroidAndroid 中的 Ping 应用程序
【发布时间】:2013-01-12 15:47:09
【问题描述】:

我正在制作一个应用程序,它将实现“ping”命令的某些功能。问题是,我不知道在 ANDROID 中使用哪个库/库。 有人知道吗?

我访问过这些 stackoverflow 链接,但它们并没有太大帮助。

【问题讨论】:

  • 您提供的链接到底有什么问题?你试过什么?
  • 您需要 ping 的哪些“功能”?
  • 往返时间延迟,丢包计算。

标签: android ping


【解决方案1】:

我用下面的代码来ping。

public String ping(String url) {
    String str = "";
    try {
        Process process = Runtime.getRuntime().exec(
                "/system/bin/ping -c 8 " + url);
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                process.getInputStream()));
        int i;
        char[] buffer = new char[4096];
        StringBuffer output = new StringBuffer();
        while ((i = reader.read(buffer)) > 0)
            output.append(buffer, 0, i);
        reader.close();

        // body.append(output.toString()+"\n");
        str = output.toString();
        // Log.d(TAG, str);
    } catch (IOException e) {
        // body.append("Error\n");
        e.printStackTrace();
    }
    return str;
}

在 url 中,您需要传递要 ping 的地址。

【讨论】:

  • 完全有帮助....我完成了一半的工作...仍然无法理解如何格式化输出?你对此有什么建议吗?
  • @mihir6692 :) 很高兴为您提供帮助。
  • 你知道如何格式化输出吗?它会更有帮助......提前谢谢......我不知道使用哪个库
  • 如何格式化输出是什么意思?你到底想用它做什么。
  • 在输出中它们都一起打印,我想像这样打印它(所有内容都在新行中):[ipaddress] [packet sequence no] [ttl] [rtt]
【解决方案2】:

感谢您研究此问题。您链接到的问题(以及 SO 上的许多其他问题)都导致使用系统的 ping 可执行文件或尝试可疑的 InetAddress.isReachable 方法的解决方案。 不过,还有第三种选择 - 如果您愿意添加一点本机代码

我最近为 Android VPN 应用程序实现了 ICMP Echo (ping) 功能。我无法使用系统“ping”可执行文件,因为它发送的 ICMP 数据包被我的 VPN 捕获,无论如何我希望能够将 ICMP 数据包从我的网络转发到外部世界并接收回复。

InetAddress.isReachable 方法对我根本不起作用(总是返回 false),正如在 SO 中彻底讨论的那样,例如herehere

我得到的解决方案是使用本机代码创建一个 ICMP 套接字,我用它来发送和接收 ICMP packets(“ping”的回显请求和回复)。 Linux 内核支持(自 2011 年以来)ICMP sockets without any special privileges 的创建。一个新的 ICMP 套接字被创建为具有协议 PROT_ICMP 的数据报套接字。在this answer 中可以看到一个很好的 C 实现示例。

ICMP 套接字功能也被 ported to Android 使用,甚至在 "ping" program 中使用。其实有人建议可以用fix the implementation of InetAddress.isReachable().

Java API 不支持此功能,但使用本机代码可以打开 ICMP 套接字。我使用JNA 来访问我需要的libC 函数(socket()、close()、sendto()、recvfrom()、poll() 等)。我想 JNI 也可以。

要绕过 VPN 限制,需要使用 VpnService.protect(int) 保护套接字文件描述符。

有几个注意事项,如 LWN article 中所述:

  • 请记住通过读取(并可能设置)“/proc/sys/net/ipv4/ping_group_range”的内容来验证您的系统是否允许 ICMP 套接字。
  • 内核修改了 ICMP 标头中的“标识符”字段,如果您打算将回复数据包转发给原始请求者,则必须重置它(并重新计算校验和)。

【讨论】:

  • 如何使用基于 java 的 VpnService.protect() 方法保护在本机代码中创建的套接字,例如您是否必须将 fd 从本机代码返回到 java 中,然后用它调用protect()?另外,如果 ping_group_range 显示为“0 2147483647”,是否意味着它已为所有人启用?
  • 自己回答:是的,只需从本机代码返回 fd 并将 int 直接传递给 VpnService.protect()。保护后,现在可以接收 ICMP 响应。
【解决方案3】:

我在纯 Android Java 中实现了“ping”并将其托管在 gitlab 上。它有几个有用的功能,比如能够绑定到给定的网络。

https://github.com/dburckh/AndroidPing

【讨论】:

    猜你喜欢
    • 2010-10-18
    • 2014-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-11
    • 2013-06-21
    • 2013-12-10
    • 2011-07-18
    相关资源
    最近更新 更多