以下代码针对/ 24 IP hostList执行254个ping请求,每个请求都在自己的线程中(或者我认为)。一个完整的/ 24子网(172.21.0.0/24)被加载到hostList中,然后在for循环中传递给worker,以启动每个线程以完成ping工作。
每个ping线程的超时为1000毫秒,因此如果将254个IP传递给254个线程,则整个过程不应超过一到两秒。
即。如果该程序确实是多线程的话,我应该可以在2秒内ping这个/ 24中的所有ip。
结果似乎是并行处理每个主机并不是并行...在使这个成为真正的多线程ping应用程序方面我做错了什么?
/*
* Step 1: Ping a subnet to find alive hosts
*/
package smartsdiscoveryrobot;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.icmp4j.IcmpPingUtil;
import org.icmp4j.IcmpPingRequest;
import org.icmp4j.IcmpPingResponse;
import org.apache.commons.net.util.SubnetUtils; // Subnet Utils to genrate host list
/**
*
* @author beukesmar
*/
public class PingExecutorService {
private static final String COMMUNITY = "public";
private static final int NUMBEROFPINGS = 1;
private static final int PINGTIMEOUT = 1000;
//Determine how many threads should be spawned by fetching the number of processors from Runtime
//private static final int NUM_THREADS = Runtime.getRuntime().availableProcessors();
private static final int NUM_THREADS = 254; //Runtime.getRuntime().availableProcessors();
public static void main(String args[]) throws Exception {
System.out.println("Availabe threads: " + NUM_THREADS);
// Instantitate new Fixed size thread pool with NUM_THREADS
ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
SubnetUtils utils = new SubnetUtils("172.21.0.1", "255.255.255.0");
System.out.println("Low Address: " + utils.getInfo().getLowAddress());
System.out.println("High Address: " + utils.getInfo().getHighAddress());
// Construct hostList with all IP's in above subnet
String[] hostList = utils.getInfo().getAllAddresses();
// Create worker for each host in hostlist
System.out.println("Host array length: " + hostList.length);
for (String host : hostList) {
Runnable worker = new MyRunnable(host, PINGTIMEOUT, COMMUNITY);
executor.execute(worker);
}
executor.shutdown();
// Wait until all threads are finish
while (!executor.isTerminated()) {
}
System.out.println("\nFinished all threads");
}
public static class MyRunnable implements Runnable {
private final String host;
private final String community;
private final int pingtimeout;
MyRunnable(String host, int pingtimeout, String community) {
this.host = host;
this.pingtimeout = pingtimeout;
this.community = community;
}
@Override
public void run() {
System.out.print("Spawning new thread to ping to host: " + host + " timeout=" + pingtimeout + "\n");
/*
Code to perform ping
*/
final IcmpPingRequest request = IcmpPingUtil.createIcmpPingRequest();
request.setHost(host);
request.setTimeout(pingtimeout);
request.setPacketSize(32); // Send 32 bytes
// Perform NUMBEROFPINGS pings per host
int numberofpings = NUMBEROFPINGS;
int numberofsuccesspings = 0;
int numberoffailedresponse = 0;
int minlatency = 0;
long avglatency = 0;
int maxlatency = 0;
int sumoflatency = 0;
long totaltime = 0;
boolean isalive = false;
boolean haspacketloss = false;
for (int i = 1; i <= numberofpings; i++) {
final IcmpPingResponse response = IcmpPingUtil.executePingRequest(request);
// host responded to a echo request
if (response.getSuccessFlag() == true) {
isalive = true;
numberofsuccesspings++;
//System.out.println("Reply from " + host + " icmp_req=" + i + " bytes=" + response.getSize() + " time=" + response.getRtt() + "ms");
// Set inital values
if (minlatency == 0) {
minlatency = response.getRtt();
maxlatency = response.getRtt();
}
// Set minlatency if response latency is lower than minlatency
if (response.getRtt() < minlatency) {
minlatency = response.getRtt();
}
// Set maxlatency if response latency is higher than maxlatency
if (response.getRtt() > maxlatency) {
maxlatency = response.getRtt();
}
sumoflatency = sumoflatency + response.getRtt();
totaltime = totaltime + response.getDuration();
// host has dropped a echo request packet
} else {
haspacketloss = true;
numberoffailedresponse++;
//System.out.println("Reply from " + host + ":Error:" + response.getErrorMessage());
totaltime = totaltime + response.getDuration();
}
//final String formattedResponse = IcmpPingUtil.formatResponse(response);
//System.out.println(host + ":" + formattedResponse);
}
long packetloss = numberoffailedresponse / numberofpings * 100;
// Dont devide by 0
if (numberofsuccesspings != 0) {
avglatency = sumoflatency / numberofsuccesspings;
}
/*System.out.println(
"---" + host + " ping statistics ---\n"
+ numberofpings + " packets transmitted, " + numberofsuccesspings + ", " + packetloss + "% packet loss, time " + totaltime + "ms\n"
+ "rtt min/avg/max = " + minlatency + "/" + avglatency + "/" + maxlatency + " ms");*/
System.out.println(host + " isalive=" + isalive + " haspacketloss=" + haspacketloss);
}
}
}
答案 0 :(得分:0)
icmp4j似乎无法并行ping,它一次只能ping 1.
我不确定为什么,猜测:可能与jna有关。
我的解决方案是使用processbuilder来执行本机ping命令。