web-dev-qa-db-ja.com

Android)のpingアプリケーション

「ping」コマンドのいくつかの機能を実装するアプリケーションを作成しています。問題は、Androidで使用するライブラリ/ライブラリがわからないことです。誰かがそれについて何か考えがありますか?

私はこれらのstackoverflowリンクにアクセスしましたが、あまり役に立ちませんでした。

11
user1944616

次のコードを使用して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を実行するアドレスを渡す必要があります。

19

問題を調査していただきありがとうございます。あなたがリンクした質問(およびSOに関する他の多くの質問)はすべて、システムのping実行可能ファイルを使用するか、疑わしい InetAddress.isReachable メソッドを試すという解決策につながります。 ただし、3番目の選択肢があります-少しネイティブコードを追加する場合

最近、Android VPNアプリケーションにICMPエコー(ping)機能を実装しました。送信するICMPパケットがVPNによってキャッチされたため、システムの「ping」実行可能ファイルを使用できませんでした。いずれにせよ、ICMPパケットをネットワークから外部に転送し、応答を受信できるようにしたかったのです。

SOで徹底的に説明されているように、InetAddress.isReachableメソッドはまったく機能しませんでした(常にfalseが返されます)。 ここ および ここ

私が到達した解決策は、ネイティブコードを使用してICMPソケットを作成することです。これは、 ICMPパケット ( " ping "のエコー要求と応答)を送受信するために使用しました。 Linuxカーネルは(2011年以降) 特別な特権のないICMPソケット の作成をサポートしています。新しいICMPソケットは、プロトコルPROT_ICMPを使用してデータグラムソケットとして作成されます。 Cでの良い実装例は この答え で見ることができます。

ICMPソケット機能は Androidに移植 であり、 "ping"プログラム でも使用されています。実際、これを使用して InetAddress.isReachable() の実装を修正できることが示唆されています。

Java APIはこの機能をサポートしていませんが、ネイティブコードを使用すると、ICMPソケットを開くことができます。 [〜#〜] jna [〜#〜] を使用して、必要なlibC関数(socket()、close()、sendto()、recvfrom()、poll()など)にアクセスしました。 )。 JNIも同様に機能すると思います。

VPNの制限を回避するには、ソケットファイル記述子を VpnService.protect(int) を使用して保護する必要があります。

LWNの記事 で説明されているように、いくつかの注意点があります。

  • 「/ proc/sys/net/ipv4/ping_group_range」の内容を読み取って(場合によっては設定して)、システムがICMPソケットを許可していることを確認することを忘れないでください。
  • カーネルはICMPヘッダーの「識別子」フィールドを変更します。応答パケットを元のリクエスターに転送する場合は、リセットする(そしてチェックサムを再計算する)必要があります。
10
Evyatar Tamir

「ping」を純粋なAndroid Javaで実装し、gitlabでホストしました。特定のネットワークにバインドできるなどの便利な機能がいくつかあります。

https://github.com/dburckh/AndroidPing

0
Dustin