实现一个用于执行 Ping 命令并监测主机可达性的线程类。它的作用是通过执行 Ping 命令来检查指定 IP 地址的主机是否可达,并获取相关的响应时间和丢包率信息。
代码中的 PingThread
类同样继承自 Thread
,意味着它可以在单独的线程中执行。
在 run
方法中,根据操作系统类型(Windows 或 Linux),构建相应的 Ping 命令,并使用 Runtime.getRuntime().exec()
方法执行该命令。通过读取命令输出的结果,解析出丢包率和响应时间的信息。
在 Windows 系统下,命令输出的行中包含 "时间=" 的字符串,从中解析出响应时间。而在 Linux 系统下,命令输出的行中同样包含 "时间=" 的字符串,但后面跟着的是以毫秒为单位的时间。根据操作系统的不同,可以使用不同的解析方式来提取响应时间。
此外,命令输出中还包含有关已发送和已接收数据包数量的信息,通过正则表达式匹配来解析出这些信息,并计算出丢包率。
根据解析出的数据,更新监控主机的状态、平均响应时间和丢包率,通过调用 monPingService
完成状态的更新。
该线程在每次 Ping 命令执行完成后会等待一段时间(这里是 5000 毫秒),然后再次执行 Ping 命令。通过 running
变量控制线程的运行状态,当调用 stopThread
方法时,将设置 running
为 false
,从而终止线程的执行。
请注意,该代码片段中使用了一些自定义的类和接口,例如 IMonPingService
,这些类和接口在代码中没有给出具体实现。因此,要使代码正常运行,需要确保相关的类和接口已经正确实现,并且适配于你的应用程序环境
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.regex.Matcher;
import java.util.regex.Pattern;public class PingThread extends Thread{private volatile boolean running = true;private Long pingId;private String ipAddress;private Long pingCount;private Long timeout;private IMonPingService monPingService;public PingThread(Long pingId, String ipAddress,Long pingCount,Long timeout, IMonPingService monPingService){this.pingId = pingId;this.ipAddress = ipAddress;this.pingCount = pingCount == null ? 5:pingCount;this.timeout = timeout == null ? 1000:timeout;this.monPingService = monPingService;}public void stopThread() {running = false;}public void run() {String os = System.getProperty("os.name").toLowerCase();String pingCommand = os.contains("win") ? "ping -n "+pingCount+" -w "+timeout+" " + ipAddress : "ping -c "+pingCount+" -W "+timeout+" " + ipAddress;System.out.println("正在 ping:"+pingCommand);while (running){try {// 执行ping命令Process process = Runtime.getRuntime().exec(pingCommand);BufferedReader reader = os.contains("win") ?new BufferedReader(new InputStreamReader(process.getInputStream(), "gbk")):new BufferedReader(new InputStreamReader(process.getInputStream(), "utf-8"));String line;int packetSent = 0;int packetReceived = 0;double totalResponseTime = 0;// 读取ping命令输出while ((line = reader.readLine()) != null) {
// System.out.println(line);// 解析ping命令输出,获取丢包率和响应时间// 来自 192.168.1.9 的回复: 字节=32 时间=1ms TTL=64if (os.contains("win") && line.contains("时间=")) {packetSent++;packetReceived++;int startIndex = line.indexOf("时间=") + 3;int endIndex = line.indexOf("ms");double responseTime = Double.parseDouble(line.substring(startIndex, endIndex).trim());totalResponseTime += responseTime;}//64 字节,来自 192.168.1.9: icmp_seq=1 ttl=64 时间=0.786 毫秒else if (os.contains("linux") && line.contains("时间=")) {packetSent++;packetReceived++;int startIndex = line.indexOf("时间=") + 3;int endIndex = line.indexOf(" 毫秒");double responseTime = Double.parseDouble(line.substring(startIndex, endIndex).trim());totalResponseTime += responseTime;} else if (line.contains("已发送") && line.contains("已接收")) {Pattern packetPattern = Pattern.compile("(\\d+) 个包");Matcher packetMatcher = packetPattern.matcher(line);if (packetMatcher.find()) {packetSent = Integer.parseInt(packetMatcher.group(1));}Pattern lossPattern = Pattern.compile("(\\d+)% 包丢失");Matcher lossMatcher = lossPattern.matcher(line);if (lossMatcher.find()) {int packetLossPercentage = Integer.parseInt(lossMatcher.group(1));packetReceived = packetSent - (packetSent * packetLossPercentage) / 100;}}}if (packetSent > 0) {double packetLossRate = (packetSent - packetReceived) / (double) packetSent * 100;double averageResponseTime = totalResponseTime / (double) packetReceived;// System.out.println("IP地址可达性:可达");
// System.out.println("平均响应时间:" + averageResponseTime + "ms");
// System.out.println("丢包率:" + packetLossRate + "%");monPingService.updateMonPingStatus(pingId, Status.OPEN, BigDecimal.valueOf(averageResponseTime),BigDecimal.valueOf(packetLossRate));} else {
// System.out.println("IP地址不可达");monPingService.updateMonPingStatus(pingId, Status.CLOSE,BigDecimal.valueOf(-1),BigDecimal.valueOf(100));}} catch (IOException e) {e.printStackTrace();}try {Thread.sleep(5000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}}