In my application I need to scan the local subnet (192.168.1.*) to collect the list of MAC addresses of all connected devices.
I currently use the following strategy:
Runtime.exec("ping -c 1 <addr>")
waitFor()
on each of the returned process to collect the exit code/proc/net/arp
file and parse the MAC addressesIn most cases, this works very well and provides a fast scan.
But on some devices (such as android 1.5, and sometimes on >=4.0), the execution gets stuck at process creation (after a few ones have been successfully started) and there's no way to kill the running thread.
Do you see anything I could try to solve this issue? Or any other strategy that would not take too long?
This can be solved by using a pool of thread running the INetAddress.isReachable() method (instead of running the ping
command in native processes).
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);
}
}
};
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With