Java 在linux VM和raspberry pi之间查找不同数量的网络节点
我有一个Java应用程序在raspberry pi上运行。我在我的Mac或linux虚拟机上开发了它(每个虚拟机都有一部分),在那里工作得很好。它也可以在pi上正常运行,但它显示了关于网络扫描功能的不同结果 它所做的是检查自己的IP地址(例如192.168.1.102),获取子网(192.168.1.),然后迭代该空间中所有可能的IP地址。对于每个IP,它发送一个ping请求(实际上是java的一种方法,我给它一个150ms的超时时间(对于普通局域网中的ping响应来说已经足够了) 我还让它在threadpoolexecutor中并行运行,其中有10个线程,每个线程处理一个IP地址 现在我的问题是:虽然它在我的VM/Mac上运行良好且一致(例如在家中30分钟内,给我一个恒定的10个节点),但它在Pi上不断波动:Java 在linux VM和raspberry pi之间查找不同数量的网络节点,java,multithreading,networking,raspberry-pi,Java,Multithreading,Networking,Raspberry Pi,我有一个Java应用程序在raspberry pi上运行。我在我的Mac或linux虚拟机上开发了它(每个虚拟机都有一部分),在那里工作得很好。它也可以在pi上正常运行,但它显示了关于网络扫描功能的不同结果 它所做的是检查自己的IP地址(例如192.168.1.102),获取子网(192.168.1.),然后迭代该空间中所有可能的IP地址。对于每个IP,它发送一个ping请求(实际上是java的一种方法,我给它一个150ms的超时时间(对于普通局域网中的ping响应来说已经足够了) 我还让它在t
### 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.
}
}
public void pingAllInSubnet(int-responseTimeout){
//创建一个线程池,最多可并行执行20个作业
ExecutorService线程池=Executors.newFixedThreadPool(20);
//提交要由池执行的作业
对于(int i=1;i好的,所以问题出在其他地方。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>();
}
}
公共HashMap getAllDevicesFromArpCache(){
HashMap节点=新的HashMap();
for(字符串行:getArpTable()){
String[]nodeInfo=line.split(“+”)//用于分割所有空间的正则表达式
//字符串的形式为:()在en0 ifscope[ethernet]上
字符串dnsName=nodeInfo[0];
字符串ipAddress=nodeInfo[1]。子字符串(1,nodeInfo[1]。长度()-1);
字符串macAddress=nodeInfo[3];
NetworkNode节点=新的NetworkNode(macAddress、dnsName、ipAddress);
nodes.put(node.getMacAddress(),node);
}
返回节点;
}
私有集getArpTable(){
Runtime rt=Runtime.getRuntime();
进程pr=null;
//一种正则表达式模式,允许我们在arp输出中搜索mac地址
Pattern macPattern=Pattern.compile(([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2});
试一试{
pr=rt.exec(“arp-a”);
字符串arp=InputStreamHelper.getStringFromInputStream(pr.getInputStream());
HashSet节点=新的HashSet(Arrays.asList(arp.split(“\n”));
Iterator it=nodes.Iterator();
while(it.hasNext()){
String node=it.next();
if(!macPattern.matcher(node.find()){
it.remove();
}
}
//对于(字符串节点:节点){System.out.println(节点);}
返回节点;
}捕获(IOE异常){
e、 printStackTrace();
返回新的HashSet();
}
}
请注意“arp-a”…一旦我将其更改为“arp-an”,它在发送回节点之前不会尝试通过dns解析节点,因此它们会立即返回。pi花了一段时间才获得dns响应,这就是为什么它有时只给我几个,有时给我所有的响应