java - 在linux VM和raspberry pi之间查找不同数量的网络节点

标签 java multithreading networking raspberry-pi

我有一个在树莓派上运行的 Java 应用程序。我在我的 Mac 或 linux VM 上开发了它(每个都有一部分)并且在那里工作得很好。它也在 pi 上运行得很好,但它向我展示了有关网络扫描功能的不同结果

它所做的是检查自己的 IP 地址(例如 192.168.1.102),获取子网 (192.168.1.),然后遍历该空间中所有可能的 IP 地址。对于每个 IP,它都会发送一个 ping 请求(实际上是一个 isReachable() java 方法。我给它一个 150 毫秒的超时(对于普通局域网中的 ping 响应来说绰绰有余)。

我还让它在一个有 10 个线程的线程池执行器中并行运行,每个线程处理一个 IP 地址。

现在我的问题是:虽然它在我的 VM/Mac 上运行良好且一致(例如在家里 30 分钟内给我一个恒定的 10 个节点),但它在 Pi 上不断波动:

### We found 2 nodes ###
### We found 6 nodes ###
### We found 4 nodes ###
### We found 7 nodes ###
### We found 5 nodes ###
### We found 4 nodes ###
### We found 4 nodes ###
### We found 3 nodes ###
### We found 7 nodes ###
### We found 5 nodes ###
### We found 2 nodes ###

(从我的控制台输出中提取)

这是 Runnable 的代码:

public void doPing() {
    try {
        InetAddress.getByName(ip).isReachable(timeout);
    } catch (IOException e) { e.printStackTrace();}

}

还有我的服务,它管理线程:

public void pingAllInSubnet(int responseTimeout) {

    // create a pool of threads, 20 max jobs will execute in parallel
    ExecutorService threadPool = Executors.newFixedThreadPool(20);
    // submit jobs to be executing by the pool
    for (int i = 1;i<255;i++) {
        //build IP to ping
        final String ipToPing = subnet + "." + i;

        threadPool.submit(new DiscoveryRunnable(ipToPing, responseTimeout));
    }

    // once you've submitted your last job to the service it should be shut down
    threadPool.shutdown();

    //see if our threads are all done
    try {
        if(!threadPool.awaitTermination(5, TimeUnit.SECONDS)){
            threadPool.shutdownNow();
        }
    } catch (InterruptedException e) {
        e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
    }
}

有人知道为什么 Pi 上的 ping 响应数量如此困惑吗?难道是

  • 与 macbook 相比,wifi 连接较差
  • 缺乏性能(700mhz cpu 与四核)
  • ...?

任何帮助将不胜感激! :) 亲切的问候

最佳答案

好的,所以问题出在其他地方。 arp 缓存中总是有所有节点,但我使用以下代码读取它:

public HashMap<String, NetworkNode> getAllDevicesFromArpCache() {
    HashMap<String, NetworkNode> nodes = new HashMap<String, NetworkNode>();
    for (String line : getArpTable()) {
        String[] nodeInfo = line.split(" +"); //regex to split all spaces
        // string is of form: <dnsname> (<ip>) at <macAddress> on en0 ifscope [ethernet]
        String dnsName = nodeInfo[0];
        String ipAddress = nodeInfo[1].substring(1, nodeInfo[1].length() - 1);
        String macAddress = nodeInfo[3];
        NetworkNode node = new NetworkNode(macAddress, dnsName, ipAddress);

        nodes.put(node.getMacAddress(), node);
    }


    return nodes;
}

private Set<String> getArpTable() {

    Runtime rt = Runtime.getRuntime();
    Process pr = null;

    //a regex pattern that lets us search the arp output for mac addresses
    Pattern macPattern = Pattern.compile("([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})");
    try {
        pr = rt.exec("arp -a");
        String arp = InputStreamHelper.getStringFromInputStream(pr.getInputStream());
        HashSet<String> nodes = new HashSet<String>(Arrays.asList(arp.split("\n")));
        Iterator<String> it = nodes.iterator();
        while (it.hasNext()) {
            String node = it.next();

            if (!macPattern.matcher(node).find()) {
                it.remove();
            }
        }


        //for(String node : nodes){System.out.println(node);}

        return nodes;
    } catch (IOException e) {
        e.printStackTrace();
        return new HashSet<String>();
    }

}

注意“arp -a”...一旦我将其更改为“arp -an”,它在发送回节点之前不会尝试通过 dns 解析节点,因此它们会立即返回。 pi 花了一段时间才得到 dns 响应,这就是为什么它有时只给我一些,有时给我所有...

关于java - 在linux VM和raspberry pi之间查找不同数量的网络节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23919099/

相关文章:

java - 如何模拟riak java客户端?

java - 如何在java中检查数组

java - 如何从 Crashlytics 中检测崩溃原因?

ios - 检查特定网络/SSID 是否可用

java - "server"上的 stub 是什么,骨架是什么意思?

networking - 如何使用功能 “send”(Winsock)在带有OpenCV的VS10中流式传输视频?

java gui - 保存和加载数据

java - volatile HashMap 不在 Thead 之外更新

c# - 使用任务并行库时线程数增长

c# - 错误 : Excepiton in System. Threading.ThreadAbortException:线程被中止