I have been reading around the topic of getting a list of devices connected to my WIFI hotspot on my phone programmatically.

I found a useful post on stack overflow with the following code and a comment saying

This is incorrect as the ARP tables don't necessarily refresh when a device disconnects. One say say, that you could simply ping all the devices in the table to see which IPs are active but it is quite possible that a device is firewalled to not respond to ICMP request and your ping would fail. This solution, although a working one, isn't robust and accurate.

I was wondering, if reading proc/net/arp isn't accurate enough due to refresh issues, how can you force the system to do a refresh to get accurate data?

private int countNumMac()
{
    int macCount = 0;
    BufferedReader br = null;
    try {
        br = new BufferedReader(new FileReader("/proc/net/arp"));
        String line;
        while ((line = br.readLine()) != null) {
            String[] splitted = line.split(" +");
            if (splitted != null && splitted.length >= 4) {
                // Basic sanity check
                String mac = splitted[3];
                if (mac.matches("..:..:..:..:..:..")) {
                    macCount++;
                }
            }
        }
    }
    catch (Exception e) {
        e.printStackTrace();
    }
    finally {
        try {
            br.close();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }

    if (macCount == 0)
        return 0;
    else
        return macCount-1; //One MAC address entry will be for the host.
}
有帮助吗?

解决方案

The ARP table is not a distributed list of "hosts that are online." It's a local-only list of "hosts that we've seen on this network."

Once you realize this, you'll note that there's no way of removing entries when someone disconnects other than trying to connect to them. Just have a continuous loop in the background, connecting to each host and sending a single ICMP packet (kinda hard to pull off from Java but Android does come with a ping command-line tool).

Granted, hosts that don't reply to ping will be filtered out but depending on the application that might be acceptable.

Alternatively, just let the user try to connect to any of the listed hosts and gracefully time out when the other party is offline. That's what most networking applications do anyway and is the only foolproof way of checking if the host is online.

其他提示

Ping may often do its arp request and get arp replies from active hosts even if the icmp echo request is subsequently blocked. Therefore ping can in some cases be used to populate the arp table in order to check it for network presence even if icmp is being actively blocked.

But if this is not accurate enough or feels too crude, network presence can be mapped directly using the arp protocol and without involving protocols higher up in the stack which stand a higher risk of being blocked.

arping is the Linux utility commonly used for manual arp level operations (on Linux).

Here is the source code for arping.

Through quick-googling it appears there are utilities for Android which perform corresponding operations, I also found source code which seems to be for arping on Google Android BusyBox.

The arping utility may be usable as is, assuming of course you ensure its presence on your phone. Alternatively one or both of the code variants may serve as inspiration as to how the problem may be programmatically solved in your own code.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top