在我的应用程序中,我需要扫描本地子网(192.168.1。*)以收集所有连接设备的MAC地址列表。
我目前使用以下策略:
Runtime.exec("ping -c 1 <addr>")
waitFor()
来收集退出代码/proc/net/arp
文件并解析MAC地址在大多数情况下,这种方法效果很好,可以快速扫描。
但是在某些设备上(例如android 1.5,有时在&gt; = 4.0),执行会在创建进程时陷入困境(在几次成功启动之后),并且没有办法杀死正在运行的线程。 / p>
您是否看到我可以尝试解决此问题的任何内容?或者其他任何不需要太长时间的策略?
答案 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);
}
}
};
}