2012-04-20 3 views
4

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

私は現在、次の戦略を使用する:

  1. 開始を同時に255 pingがプロセスの終了コードを
  2. 近い入力ストリームを収集し、破壊するために返されるプロセスのそれぞれにRuntime.exec("ping -c 1 <addr>")
  3. 使用waitFor()とコマンドそれらを
  4. ファイルを読み取り、MACアドレスを解析します。

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

しかし、いくつかのデバイス(アンドロイド1.5、時には4.0以上)では、プロセスの作成時に(いくつかのデバイスが正常に起動した後)実行が停止し、実行中のスレッドを強制終了する方法がありません。

この問題を解決するために何かできることはありますか?あまり時間がかからない他の戦略もありますか?

答えて

7

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

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); 
      } 
     } 
    }; 
} 
関連する問題