The essence of the task is to enter 3 ip addresses and ping them, write the average response time to an array and return it, but the program does not write and does not even reach the method (type error), how can I fix it?
public static void main(String[] args) throws Exception {
System.out.println("Введите 3 IP адреса: ");
ArrayList<String> ip = new ArrayList<>();
ArrayList<String> averageTime = new ArrayList<>();
Scanner scr = new Scanner(System.in);
for (int i = 0; i < 3; i ) {
ip.add(scr.nextLine());
averageTime.add(getAverageTime(ip.get(i))); //error here
}
System.out.println(averageTime);
}
public static ArrayList<String> getAverageTime(String ip) throws IOException {
String command = String.format("ping %s | ForEach-Object {if($_ -match 'Average = (\\d )'){$Matches[1]}}", ip);
ProcessBuilder builder = new ProcessBuilder(
"powershell.exe", "/c", command);
builder.redirectErrorStream(true);
Process p = builder.start();
BufferedReader r = new BufferedReader(new
InputStreamReader(p.getInputStream()));
ArrayList<String> averageTime = new ArrayList<>();
while (true) {
//line = r.readLine();
averageTime.add(r.readLine());
//System.out.println(averageTime);
if (averageTime == null) {
break;
}
}
System.out.println(averageTime);
return averageTime;
}
CodePudding user response:
ArrayList<String> averageTime = new ArrayList<>();
while (true) {
//line = r.readLine();
averageTime.add(r.readLine());
//System.out.println(averageTime);
if (averageTime == null) {
break;
}
}
the problem is in this block. while(true)
creates infinite loop. And averageTime
will never become null - so condition for break will never be achieved
Instead of true you should have a condition that check that r.readLine is not null or something:
String line = null;
while ((String line = r.readline()) != null) {
averageTime.add(line);
}
Google how to use java bufferedReader
to learn about it more
CodePudding user response:
Use Java code to parse the output of the ping
command. The below code demonstrates for one IP address but I assume you can expand it to meet your needs. Note that the code uses regular expressions to parse the ping
command output but you can use any method you like to parse the output. Also you don't have to use Scanner to read the ping
output, you can use any method you like to read it.
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PingAvgs {
public static void main(String[] args) {
Pattern pttrn = Pattern.compile("Average = (\\d )ms$");
ProcessBuilder pb = new ProcessBuilder("ping.exe", ipAddress);
try {
Process p = pb.start();
InputStream is = p.getInputStream();
try (Scanner s = new Scanner(is)) {
while (s.hasNextLine()) {
String line = s.nextLine();
Matcher mtchr = pttrn.matcher(line);
if (mtchr.find()) {
System.out.println("Average = " mtchr.group(1));
}
}
}
int status = p.waitFor();
}
catch (IOException | InterruptedException x) {
x.printStackTrace();
}
}
}
Running the above code produces the following output:
Average = 0
Edit
Here is a solution closer to the code in your question.
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PingAvgs {
/** Regex to extract average time from "ping" command output. */
private static final Pattern PTTRN = Pattern.compile("Average = (\\d )ms$");
/**
* Returns the average time from the output of the "ping" command. Returns zero if "ping"
* command fails or "ping" output does not contain an average, for example when "ping" request
* times out.
*
* @param ipAddress - the IP address to "ping".
*
* @return The average that appears in the "ping" command output.
*
* @throws InterruptedException if interrupt occurs while waiting for "ping" command termination.
* @throws IOException if error occurs reading "ping" command output.
*/
private static int getAverageTime(String ipAddress) throws InterruptedException, IOException {
int average = 0;
System.out.println("Pinging " ipAddress);
ProcessBuilder pb = new ProcessBuilder("ping.exe", "127.0.0.1");
Process p = pb.start();
InputStream is = p.getInputStream();
try (Scanner s = new Scanner(is)) {
while (s.hasNextLine()) {
String line = s.nextLine();
Matcher mtchr = PTTRN.matcher(line);
if (mtchr.find()) {
average = Integer.parseInt(mtchr.group(1));
}
}
}
int status = p.waitFor();
if (status != 0) {
System.out.println("'ping' command failed for IP " ipAddress);
}
System.out.println("average = " average);
return average;
}
public static void main(String[] args) {
List<Integer> averages = new ArrayList<>(3);
List<String> ipAdresses = List.of("127.0.0.1", "127.0.0.1", "127.0.0.1");
try {
for (String ipAddress : ipAdresses) {
averages.add(getAverageTime(ipAddress));
}
System.out.println("Averages:");
averages.forEach(System.out::println);
}
catch (Exception x) {
x.printStackTrace();
}
}
}
Running the above code produces the following output:
Pinging 127.0.0.1
average = 0
Pinging 127.0.0.1
average = 0
Pinging 127.0.0.1
average = 0
Averages:
0
0
0