Android子网扫描

时间:2012-04-20 08:57:12

标签: android process ping subnet network-scan

在我的应用程序中,我需要扫描本地子网(192.168.1。*)以收集所有连接设备的MAC地址列表。

我目前使用以下策略:

  1. 使用Runtime.exec("ping -c 1 <addr>")
  2. 同时启动255个ping命令
  3. 在每个返回的进程上使用waitFor()来收集退出代码
  4. 关闭输入流程并销毁它们
  5. 阅读/proc/net/arp文件并解析MAC地址
  6. 在大多数情况下,这种方法效果很好,可以快速扫描。

    但是在某些设备上(例如android 1.5,有时在&gt; = 4.0),执行会在创建进程时陷入困境(在几次成功启动之后),并且没有办法杀死正在运行的线程。 / p>

    您是否看到我可以尝试解决此问题的任何内容?或者其他任何不需要太长时间的策略?

1 个答案:

答案 0 :(得分: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);
            }
        }
    };
}