安卓子网扫描

4
在我的应用中,我需要扫描本地子网(192.168.1.*)以收集所有已连接设备的MAC地址列表。
我目前使用以下策略:
1.同时启动255个ping命令:`Runtime.exec("ping -c 1 ")`
2.在每个返回进程上使用`waitFor()`来收集退出代码
3.关闭进程的输入流并销毁它们
4.读取`/proc/net/arp`文件并解析MAC地址
在大多数情况下,这种方法非常有效,并提供快速扫描。但是在某些设备上(例如Android 1.5,有时在>=4.0),执行会卡在进程创建时(在成功启动几个进程后),没有办法杀死运行线程。
您是否看到我可以尝试解决此问题的任何方法?或者任何其他不需要太长时间的策略?
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);
            }
        }
    };
}

你是我的英雄。 - famfamfam
你好。我可以问一个问题吗?在运行你的代码后,我发现有时候 isReachable 返回 false,即使我的地址是活动的 -> 你能帮我解释一下吗?如果你需要更多信息,我可以创建一个问题帖子。 - famfamfam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接