4

私のアプリケーションでは、ローカルサブネット(192.168.1。*)をスキャンして、接続されているすべてのデバイスのMACアドレスのリストを収集する必要があります。

私は現在、次の戦略を使用しています。

  1. 同時に255のpingコマンドを開始しますRuntime.exec("ping -c 1 <addr>")
  2. 返された各プロセスで使用waitFor()して、終了コードを収集します
  3. プロセスの入力ストリームを閉じて、それらを破棄します
  4. ファイルを読み取り、/proc/net/arpMACアドレスを解析します

ほとんどの場合、これは非常にうまく機能し、高速スキャンを提供します。

ただし、一部のデバイス(android 1.5など、場合によっては4.0以上)では、プロセスの作成時に実行が停止し(いくつかのデバイスが正常に開始された後)、実行中のスレッドを強制終了する方法がありません。

この問題を解決するために私が試みることができる何かを見ますか?または、それほど長くはかからない他の戦略はありますか?

4

1 に答える 1

8

これは、(ネイティブプロセスでコマンドを実行する代わりに)INetAddress.isReachable()メソッドを実行するスレッドのプールを使用することで解決できます。ping

private static final int NB_THREADS = 10;

public void doScan() {
    Log.i(LOG_TAG, "Start scanning");

    ExecutorService executor = Executors.newFixedThreadPool(NB_THREADS);
    for(int dest=0; dest<255; dest++) {
        String host = "192.168.1." + dest;
        executor.execute(pingRunnable(host));
    }

    Log.i(LOG_TAG, "Waiting for executor to terminate...");
    executor.shutdown();
    try { executor.awaitTermination(60*1000, TimeUnit.MILLISECONDS); } catch (InterruptedException ignored) { }

    Log.i(LOG_TAG, "Scan finished");
}

private Runnable pingRunnable(final String host) {
    return new Runnable() {
        public void run() {
            Log.d(LOG_TAG, "Pinging " + host + "...");
            try {
                InetAddress inet = InetAddress.getByName(host);
                boolean reachable = inet.isReachable(1000);
                Log.d(LOG_TAG, "=> Result: " + (reachable ? "reachable" : "not reachable"));
            } catch (UnknownHostException e) {
                Log.e(LOG_TAG, "Not found", e);
            } catch (IOException e) {
                Log.e(LOG_TAG, "IO Error", e);
            }
        }
    };
}
于 2012-04-20T14:55:06.507 に答える