12

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

我已经访问了这些 stackoverflow 链接,但它们不是很有帮助。

4

3 回答 3

22

我使用以下代码来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 的地址。

于 2013-01-29T06:18:30.137 回答
14

Thank you for researching the issue. The questions you've linked to (and many others on SO) all lead to the solutions of using either the system's ping executable or trying the dubious InetAddress.isReachable method. There is, however, a third alternative - if you're willing to add a little native code.

I have recently implemented ICMP Echo (ping) functionality for an Android VPN application. I couldn't use the system "ping" executable as the ICMP packets it sends were caught by my VPN, and at any rate I wanted to be able to forward ICMP packets from my network to the outside world and receive the replies.

The InetAddress.isReachable method didn't work for me at all (always returned false), as has been discussed thoroughly in SO, e.g. here and here.

The solution I arrived at is using native code to create an ICMP socket, which I used to send and receive ICMP packets (Echo requests and replies for "ping"). The Linux kernel supports (since 2011) the creation of ICMP sockets without any special privileges. A new ICMP socket is created as a Datagram socket with the protocol PROT_ICMP. A good implementation example in C can be seen in this answer.

The ICMP socket functionality has been ported to Android as well, and even used in the "ping" program. In fact it has been suggested that it can be used to fix the implementation of InetAddress.isReachable().

Java API does not support this functionality, but using native code it is possible to open ICMP sockets. I used JNA to access the libC functions I needed (socket(), close(), sendto(), recvfrom(), poll(), etc.). I suppose JNI would work just as well.

To get around the VPN limitation, the socket file descriptor needs to be protected using VpnService.protect(int).

There are a couple of caveats, as explained in the LWN article:

  • Remember to verify that your system allows ICMP sockets, by reading (and possibly setting) the contents of "/proc/sys/net/ipv4/ping_group_range".
  • The kernel modifies the "identifier" field in the ICMP header, you will have to reset it (and recompute the checksum) if you intend to forward the reply packet to the original requester.
于 2016-05-26T09:13:16.653 回答
2

I implemented "ping" in pure Android Java and hosted it on gitlab. It's has a couple useful features like being able to bind to a given Network.

https://github.com/dburckh/AndroidPing

于 2019-01-20T20:52:35.843 回答