Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ping multiple servers in Java [duplicate]

I have a program which sends a ping request to the servers. The list is large and if an IP is unreachable it takes time to go to the next IP.

I wish that, for every IP, it should create a new thread & process all of them simultaneously.

Here is the code:

for (int i = 0; i < 89; i++)
{
     ProcessBuilder processBuilder = new ProcessBuilder("ping", isWindows? "-n" : "-c", "1", buttons[i].getText());
     Process proc = processBuilder.start();
     returnVal = proc.waitFor();                       
}

How can I make this code to ping all IPs, each in a separate thread ?

like image 499
Harshit Avatar asked May 31 '15 08:05

Harshit


2 Answers

How about doing without ProcessBuilder as suggested by others also.

I have three classes - PingParallel is my main class, PingTask is the task performed by each thread, and PingResult is having result code (we can add some more info also, status message etc.).

PingParallel

package com.test.thread;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class PingParallel {

    public static void main(String[] args) {
        int totalIps = 89;
        ExecutorService executor = Executors.newFixedThreadPool(totalIps);
        List<Future<PingResult>> list = new ArrayList<Future<PingResult>>();
        Callable<PingResult> callable = null;
        for(int i=0; i< totalIps; i++){
            callable = new PingTask("127.0.0"+i); // Get the ipAddres buttons[i].getText());
            Future<PingResult> future = executor.submit(callable);
            list.add(future);
        }
        for(Future<PingResult> fut : list){
            try {
                System.out.println(new Date()+ "::"+fut.get());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        executor.shutdown();
    }
}

PingTask

package com.test.thread;

import java.net.InetAddress;
import java.util.concurrent.Callable;

public class PingTask implements Callable<PingResult> {

  private String ipAddress;

  public PingTask(String ipAddress) {
    this.ipAddress = ipAddress;
  }

  @Override
  public PingResult call() {
    InetAddress inet = null;
    try {
      inet = InetAddress.getByName(ipAddress);
      int resultCode = inet.isReachable(5000) ? 0 : -1;
      return new PingResult(ipAddress, resultCode);
    } catch (Exception e) {
      e.printStackTrace();
      return new PingResult(ipAddress, -1);
    }
  }
}

PingResult

package com.test.thread;

public class PingResult {

  private String ipAddress;
  private int resultCode;

  public PingResult(String ipAddress, int resultCode) {
    this.ipAddress = ipAddress;
    this.resultCode = resultCode;
  }

  public String getIpAddress() {
    return ipAddress;
  }

  public int getResultCode() {
    return resultCode;
  }

  public String toString() {
    return "IpAddress :: "+ ipAddress + " Result Code : "+ resultCode;
  }
}
like image 114
TheCodingFrog Avatar answered Oct 13 '22 11:10

TheCodingFrog


ProcessBuilder does invoke a new process, but you are effectively killing the parallelism by calling waitFor, since that will wait for the first process to complete before launching the next, making the calls sequential instead. You could either use PB and skip the wait calls, or perhaps use ordinary java threads wrapping calls to Runtime.exec instead.

like image 33
JHH Avatar answered Oct 13 '22 09:10

JHH