以编程方式刷新ARP表

时间:2013-12-15 08:40:39

标签: java android linux networking arp

我一直在阅读以编程方式获取连接到手机上的WIFI热点的设备列表的主题。

我找到了useful post on stack overflow,其中包含以下代码和评论

  

这是不正确的,因为当a表时,ARP表不一定要刷新   设备断开连接。有人说,你可以简单地ping所有   表中的设备可以查看哪些IP处于活动状态,但确实如此   可能是设备被防火墙以不响应ICMP请求   你的ping会失败。这个解决方案虽然是工作解决方案,但却不是   健壮而准确。

我想知道,如果由于刷新问题而读取proc / net / arp不够准确,那么如何强制系统进行刷新以获得准确的数据呢?

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.
}

2 个答案:

答案 0 :(得分:3)

ARP表不是“在线主机”的分布式列表。这是我们在这个网络上看到的“主机”的本地列表。

一旦你意识到这一点,你会注意到当有人断开连接而不是试图连接它们时,没有办法删除条目。只需在后台连续循环,连接到每个主机并发送一个ICMP数据包(有点难以从Java中移除,但Android确实附带了ping命令行工具)。

当然,不会回复ping的主机将被过滤掉,但取决于可能接受的应用程序。

或者,只需让用户尝试连接到任何列出的主机,并在对方离线时正常超时。这就是大多数网络应用程序无论如何都要做的,也是检查主机是否在线的唯一万无一失的方法。

答案 1 :(得分:1)

Ping可能经常执行其arp请求并从活动主机获取arp回复,即使随后阻止了icmp echo请求。因此,在某些情况下,ping可以用于填充arp表,以便检查网络是否存在,即使icmp被主动阻止也是如此。

但是如果这不够准确或者感觉太粗糙,可以使用arp协议直接映射网络状态,并且不会涉及堆栈中更高的协议,这会更有可能被阻止。

arping是常用于手动arp级别操作的Linux实用程序(在Linux上)。

Here是arping的源代码。

通过快速搜索,似乎有适用于Android的实用程序执行相应的操作,我还找到了source code which seems to be for arping on Google Android BusyBox

arping实用程序可以按原样使用,当然您可以确保它在手机上存在。或者,一个或两个代码变体可以作为如何在您自己的代码中以编程方式解决问题的灵感。