Java icmp4j多线程ping不那么多线程

时间:2016-08-13 17:26:55

标签: java multithreading

以下代码针对/ 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);
        }
    }
}

1 个答案:

答案 0 :(得分:0)

icmp4j似乎无法并行ping,它一次只能ping 1.

我不确定为什么,猜测:可能与jna有关。

我的解决方案是使用processbuilder来执行本机ping命令。