Java网络编程-Ping监测

article/2023/9/24 22:18:23

实现一个用于执行 Ping 命令并监测主机可达性的线程类。它的作用是通过执行 Ping 命令来检查指定 IP 地址的主机是否可达,并获取相关的响应时间和丢包率信息。

代码中的 PingThread 类同样继承自 Thread,意味着它可以在单独的线程中执行。

run 方法中,根据操作系统类型(Windows 或 Linux),构建相应的 Ping 命令,并使用 Runtime.getRuntime().exec() 方法执行该命令。通过读取命令输出的结果,解析出丢包率和响应时间的信息。

在 Windows 系统下,命令输出的行中包含 "时间=" 的字符串,从中解析出响应时间。而在 Linux 系统下,命令输出的行中同样包含 "时间=" 的字符串,但后面跟着的是以毫秒为单位的时间。根据操作系统的不同,可以使用不同的解析方式来提取响应时间。

此外,命令输出中还包含有关已发送和已接收数据包数量的信息,通过正则表达式匹配来解析出这些信息,并计算出丢包率。

根据解析出的数据,更新监控主机的状态、平均响应时间和丢包率,通过调用 monPingService 完成状态的更新。

该线程在每次 Ping 命令执行完成后会等待一段时间(这里是 5000 毫秒),然后再次执行 Ping 命令。通过 running 变量控制线程的运行状态,当调用 stopThread 方法时,将设置 runningfalse,从而终止线程的执行。

请注意,该代码片段中使用了一些自定义的类和接口,例如 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);}}}}


http://www.ngui.cc/article/show-1200757.html

相关文章

Kafka集群安装部署

Kafka集群安装部署 简介 Kafka是一款分布式的、去中心化的、高吞吐低延迟、订阅模式的消息队列系统。 同RabbitMQ一样,Kafka也是消息队列。不过RabbitMQ多用于后端系统,因其更加专注于消息的延迟和容错。 Kafka多用于大数据体系,因其更加…

java-函数式接口和Stream流

java-函数式接口和Stream流 一、函数式接口 1.1函数式接口概述 概念 有且仅有一个抽象方法的接口 如何检测一个接口是不是函数式接口 FunctionalInterface 放在接口定义的上方:如果接口是函数式接口,编译通过;如果不是,编译失败…

Delphi数据库处理组件BDE、ADO、InterBase和dbExpress详细说明

第一节 BDE、ADO、InterBase和dbExpress Delphi中处理数据库主要有两种方法,也就是BDE、ADO,从Delphi 6.0开始还加入了一种dbExpress方法。 另外,Delphi还提供了专门处理Borland 公司自己的数据库产品InterBase 数据库的专门的方法。 …

浅谈deque,queue,stack

deque 和 queue 都是常用于存储元素的容器,但它们在数据结构和应用场景上有一些区别。 queue 是队列的一种实现,它只能从队首插入元素,而只能从队尾获取并移除元素。即,queue 满足 FIFO(先进先出)的特性。…

python实现Canny算子边缘检测算法

边缘检测是一种将图片中关键信息表现出来的一种图片技术,它的结果并不是字面意思上的获取图片边缘,而是将图片有用的信息勾勒出来,类似素描的结果,但是已经去掉了很多信息。如下所示,一张原始的图片是这样的&#xff1…

GEE:批量下载每日数据集

遇到最大的困难就是GEE的客户端和服务端的数据处理问题,不过好在解决了。 我的问题是如何在GEE平台下载每天的哨兵5号(Sentinel-5P)的臭氧影像? 01 代码说明 首先,自定义参数。 // 自定义参数 var start_time 2022-07-01 var end_time …

pnpm对npm及yarn降维打击详解

目录 正文npm2yarnpnpm总结 正文 大家最近是不是经常听到 pnpm,我也一样。今天研究了一下它的机制,确实厉害,对 yarn 和 npm 可以说是降维打击。 那具体好在哪里呢? 我们一起来看一下。 我们按照包管理工具的发展历史&#xf…

【新星计划】数据库行列转换初识

数据库行列转换初识 古早时代聚合函数结合条件函数使用子查询和计算列进行附加列sqlserver pivot/unpivot列转行使用 unpivot行转列使用 pivot动态生成行列转换 sql 指令 小结文后语 古早时代 在很久很久以前,有。。。走错片场了。。。 在很早的时候,数…

听劝 不要盲目的学网络安全。

听劝 不要盲目的学网络安全。 1.这是一条坚持的道路,三分钟的热情可以放弃往下看了. 2.多练多想,不要离开了教程什么都不会了.最好看完教程自己独立完成技术方面的开发. 3.有时多 google,baidu,我们往往都遇不到好心的大神,谁会无聊天天给你做解答. 4.遇到实在搞不懂的,可…

国产新秀---XS5018A,芯昇,图像信号处理芯片

国产视频处理芯片,大崛起。 XS5018A 是一款针对 CMOS 图像传感器的高性价比图像信号处理芯片,支持 1M/2M 像素 图像传感器,一组 10-bit DVP 输入接口, ISP 具备优异的 3D 降噪功能,标清模拟输出支持 960…