[关闭]
@liruiyi962464 2025-07-22T07:15:24.000000Z 字数 8737 阅读 136

ping

代码


自己写的ping

  1. public void monitorUseState() {
  2. List<ZcMonitor> zcMonitorList = zcMonitorService.list();
  3. Integer flag = 0;
  4. if(zcMonitorList.size() > 0 && zcMonitorList != null) {
  5. for (int i = 0; i < zcMonitorList.size(); i++) {
  6. String ip = zcMonitorList.get(i).getIp();
  7. String name = zcMonitorList.get(i).getName();
  8. String position = zcMonitorList.get(i).getPosition();
  9. // 当返回值是true时,说明监控IP是可用的,false则不可。
  10. int timeOut = 3000; // 超时应该在3钞以上
  11. boolean status = false;
  12. try {
  13. // status = InetAddress.getByName(ip).isReachable(timeOut);
  14. InetAddress address = InetAddress.getByName(ip);
  15. System.out.println("开始检查 IP 地址 " + ip + " 是否可达...");
  16. long startTime = System.currentTimeMillis();
  17. status = address.isReachable(timeOut);
  18. long endTime = System.currentTimeMillis();
  19. System.out.println("检查完成,耗时:" + (endTime - startTime) + " 毫秒");
  20. if (status) {
  21. System.out .println("IP 地址 " + ip + " 是可达的");
  22. } else {
  23. System.out.println("IP 地址 " + ip + " 不可达");
  24. }
  25. } catch (IOException e) {
  26. e.printStackTrace();
  27. }
  28. //System.err.println("监控ip"+ip+"状态"+status);
  29. //onlineOrNot lineOrNot = new onlineOrNot();
  30. //String userAndPwd = onlineOrNot.userAndPwd(ip, username, password);
  31. if (!status) {
  32. // 状态更新到数据库
  33. zcMonitorList.get(i).setUseState("1");
  34. zcMonitorService.updateById(zcMonitorList.get(i));
  35. // 离线(在线状态不用推送)
  36. System.err.println("监控IP:【"+ip+"】监控名称:【"+name+"】监控位置:【"+position+"】【已离线】");
  37. zcWarningInformationService.warnXiaoxi(3,"监控IP:【"+ip+"】监控名称:【"+name+"】监控位置:【"+position+"】【已离线】",zcMonitorList.get(i));
  38. }else {
  39. // 状态更新到数据库
  40. zcMonitorList.get(i).setUseState("2");
  41. zcMonitorService.updateById(zcMonitorList.get(i));
  42. }
  43. }
  44. }
  45. }

使用工具类

  1. public Result<?> pingDevice(@RequestParam(name="ip") String ip) throws Exception {
  2. List<String> pingContent = new ArrayList<>();
  3. boolean b = Ping.ping(ip);
  4. if (b){
  5. pingContent = Ping.pingA(ip);
  6. } else {
  7. String message = "目标主机"+ip+"无法访问,请检查!";
  8. pingContent.add(message);
  9. }
  10. return Result.OK(pingContent);
  11. }

多线程定时任务(带线程池) 带参数ping

  1. package org.jeecg.modules.quartz.job;
  2. import lombok.SneakyThrows;
  3. import lombok.extern.slf4j.Slf4j;
  4. import org.jeecg.common.util.RedisUtil;
  5. import org.jeecg.modules.demo.alarmManagement.entity.AlarmRecord;
  6. import org.jeecg.modules.demo.alarmManagement.service.IAlarmRecordService;
  7. import org.jeecg.modules.demo.ping.Ping;
  8. import org.jeecg.modules.demo.system.entity.DeviceInfo;
  9. import org.jeecg.modules.demo.system.service.IDeviceInfoService;
  10. import org.jeecg.modules.message.websocket.WebSocket;
  11. import org.quartz.Job;
  12. import org.quartz.JobExecutionContext;
  13. import org.quartz.JobExecutionException;
  14. import org.springframework.beans.factory.annotation.Autowired;
  15. import java.text.SimpleDateFormat;
  16. import java.util.Date;
  17. import java.util.List;
  18. import java.util.concurrent.*;
  19. /**
  20. * 多线程定时任务(带线程池)
  21. * @Author Scott
  22. */
  23. @Slf4j
  24. public class PingLuYouJob implements Job {
  25. @Autowired
  26. private IDeviceInfoService deviceInfoService;
  27. @Autowired
  28. private IAlarmRecordService alarmRecordService;
  29. @Autowired
  30. private WebSocket webSocket;
  31. @Autowired
  32. private RedisUtil redisUtil;
  33. // 定义线程池参数
  34. private static final int CORE_POOL_SIZE = 5; // 核心线程数
  35. private static final int MAX_POOL_SIZE = 10; // 最大线程数
  36. private static final int QUEUE_CAPACITY = 100; // 队列容量
  37. @SneakyThrows
  38. @Override
  39. public void execute(JobExecutionContext context) throws JobExecutionException {
  40. // 获取设备信息列表
  41. List<DeviceInfo> deviceInfoList = deviceInfoService.list();
  42. // 创建线程池
  43. ExecutorService executor = new ThreadPoolExecutor(
  44. CORE_POOL_SIZE,
  45. MAX_POOL_SIZE,
  46. 60L, TimeUnit.SECONDS,
  47. new LinkedBlockingQueue<>(QUEUE_CAPACITY)
  48. );
  49. // 用于收集检测结果
  50. ConcurrentHashMap<String, Boolean> pingResults = new ConcurrentHashMap<>();
  51. try {
  52. // 提交所有ping任务到线程池
  53. int maxAttempts = 5; // 最大尝试5次
  54. int successThreshold = 3; // 成功3次即认为可用
  55. int timeoutPerAttempt = 3000; // 每次ping超时3秒
  56. for (DeviceInfo deviceInfo : deviceInfoList) {
  57. String targetIp = deviceInfo.getIp();
  58. executor.submit(() -> {
  59. boolean result = false;
  60. try {
  61. // result = Ping.ping(ip);
  62. result = Ping.pingWithRetry(targetIp, maxAttempts, successThreshold, timeoutPerAttempt);
  63. } catch (Exception e) {
  64. result = false;
  65. }
  66. pingResults.put(targetIp, result);
  67. });
  68. }
  69. // 关闭线程池并等待任务完成
  70. executor.shutdown();
  71. if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
  72. log.warn("线程池未在指定时间内完成所有任务");
  73. }
  74. // 处理检测结果
  75. for (DeviceInfo deviceInfo : deviceInfoList) {
  76. String ip = deviceInfo.getIp();
  77. boolean pingResult = pingResults.getOrDefault(ip, false);
  78. if (pingResult) {
  79. deviceInfo.setState("1");
  80. } else {
  81. if ("1".equals(deviceInfo.getState())) {
  82. // 添加报警记录
  83. AlarmRecord alarmRecord = new AlarmRecord();
  84. alarmRecord.setDeviceId(deviceInfo.getId());
  85. alarmRecord.setAlarmContent(deviceInfo.getName() + "设备未ping通,设备处于离线状态;");
  86. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  87. alarmRecord.setAlarmTime(sdf.format(new Date()));
  88. alarmRecord.setAlarmType("1");
  89. alarmRecordService.save(alarmRecord);
  90. // 推送告警信息
  91. String[] usersRecord = alarmRecordService.getSetUsersRecord();
  92. webSocket.sendMessage(usersRecord, "-" + deviceInfo.getName() + "设备未ping通,设备处于离线状态;" + "$" + sdf.format(new Date()));
  93. // 删除redis缓存
  94. redisUtil.del(deviceInfo.getId());
  95. }
  96. deviceInfo.setState("0");
  97. deviceInfo.setSimState("0");
  98. deviceInfo.setModuleState("0");
  99. }
  100. deviceInfoService.updateById(deviceInfo);
  101. }
  102. } catch (InterruptedException e) {
  103. Thread.currentThread().interrupt();
  104. log.error("线程池被中断", e);
  105. } finally {
  106. executor.shutdownNow(); // 确保线程池关闭
  107. }
  108. }
  109. }

Ping.java

  1. package org.jeecg.modules.demo.ping;
  2. import java.io.BufferedReader;
  3. import java.io.IOException;
  4. import java.io.InputStreamReader;
  5. import java.net.InetAddress;
  6. import java.net.UnknownHostException;
  7. import java.util.ArrayList;
  8. import java.util.List;
  9. import java.util.regex.Matcher;
  10. import java.util.regex.Pattern;
  11. public class Ping {
  12. public static boolean ping(String ipAddress) throws Exception {
  13. int timeOut = 3000 ; // 超时应该在3钞以上
  14. boolean status = InetAddress.getByName(ipAddress).isReachable(timeOut); // 当返回值是true时,说明host是可用的,false则不可。
  15. return status;
  16. }
  17. /**
  18. * 带重试机制的Ping检测方法
  19. * @param ipAddress 目标主机IP地址(如:"8.8.8.8")
  20. * @param maxAttempts 最大尝试次数(建议3-5次,根据网络稳定性调整)
  21. * @param successThreshold 成功判定阈值(建议设置为maxAttempts的60%-80%)
  22. * @param timeoutPerAttempt 单次尝试超时时间(单位:毫秒,建议3000-5000ms)
  23. * @return 达到成功阈值返回true,否则返回false
  24. */
  25. public static boolean pingWithRetry(String ipAddress, int maxAttempts, int successThreshold, int timeoutPerAttempt) {
  26. int successCount = 0;
  27. for (int i = 0; i < maxAttempts; i++) {
  28. try {
  29. boolean isReachable = InetAddress.getByName(ipAddress).isReachable(timeoutPerAttempt);
  30. if (isReachable) {
  31. successCount++;
  32. System.out.println("Attempt " + (i + 1) + ": Success");
  33. // 提前退出条件:成功次数达到阈值
  34. if (successCount >= successThreshold) {
  35. return true;
  36. }
  37. } else {
  38. System.out.println("Attempt " + (i + 1) + ": Failed");
  39. }
  40. // 可选:添加短暂间隔避免频繁请求(例如1秒)
  41. Thread.sleep(1000);
  42. } catch (UnknownHostException e) {
  43. System.err.println("Invalid host: " + e.getMessage());
  44. return false;
  45. } catch (IOException e) {
  46. System.err.println("IO Error: " + e.getMessage());
  47. return false;
  48. } catch (InterruptedException e) {
  49. Thread.currentThread().interrupt();
  50. System.err.println("Thread interrupted");
  51. return false;
  52. }
  53. }
  54. System.out.println("Final success count: " + successCount + "/" + maxAttempts);
  55. return successCount >= successThreshold;
  56. }
  57. public static void main(String[] args) {
  58. String targetIp = "8.8.8.8"; // 示例IP
  59. int maxAttempts = 5; // 最大尝试5次
  60. int successThreshold = 3; // 成功3次即认为可用
  61. int timeoutPerAttempt = 3000; // 每次ping超时3秒
  62. boolean finalStatus = pingWithRetry(targetIp, maxAttempts, successThreshold, timeoutPerAttempt);
  63. System.out.println("Host is reachable: " + finalStatus);
  64. }
  65. public static List<String> ping02(String ipAddress) throws Exception {
  66. List<String> outputLines = new ArrayList<>(); // 用于保存输出的集合
  67. try {
  68. Process pro = Runtime.getRuntime().exec("ping " + ipAddress);
  69. BufferedReader buf = new BufferedReader( new InputStreamReader(
  70. pro.getInputStream(),"GBK"));
  71. int i =1;
  72. String line = null;
  73. while ((line = buf.readLine()) != null)
  74. System.out.println(line);
  75. outputLines.add(line);
  76. } catch (Exception ex) {
  77. System.out.println(ex.getMessage());
  78. }
  79. return outputLines;
  80. }
  81. public static boolean ping(String ipAddress, int pingTimes, int timeOut) {
  82. BufferedReader in = null;
  83. Runtime r = Runtime.getRuntime(); // 将要执行的ping命令,此命令是windows格式的命令
  84. String pingCommand = "ping " + ipAddress + " -n " + pingTimes + " -w " + timeOut;
  85. try { // 执行命令并获取输出
  86. System.out.println(pingCommand);
  87. Process p = r.exec(pingCommand);
  88. if (p == null) {
  89. return false;
  90. }
  91. in = new BufferedReader( new InputStreamReader(p.getInputStream())); // 逐行检查输出,计算类似出现=23ms TTL=62字样的次数
  92. int connectedCount = 0;
  93. String line = null;
  94. while ((line = in.readLine()) != null) {
  95. connectedCount += getCheckResult(line);
  96. } // 如果出现类似=23ms TTL=62这样的字样,出现的次数=测试次数则返回真
  97. return connectedCount == pingTimes;
  98. } catch (Exception ex) {
  99. ex.printStackTrace(); // 出现异常则返回假
  100. return false;
  101. } finally {
  102. try {
  103. in.close();
  104. } catch (IOException e) {
  105. e.printStackTrace();
  106. }
  107. }
  108. }
  109. // 若line含有=18ms TTL=16字样,说明已经ping通,返回1,否則返回0.
  110. private static int getCheckResult(String line) { // System.out.println("控制台输出的结果为:"+line);
  111. Pattern pattern = Pattern.compile("(\\d+ms)(\\s+)(TTL=\\d+)", Pattern.CASE_INSENSITIVE);
  112. Matcher matcher = pattern.matcher(line);
  113. while (matcher.find()) {
  114. return 1;
  115. }
  116. return 0;
  117. }
  118. public static List<String> pingA(String ipAddress){
  119. List<String> outputLines = new ArrayList<>(); // 用于保存输出的集合
  120. try {
  121. // 创建一个Process实例执行ping命令
  122. Process process = Runtime.getRuntime().exec("ping " + ipAddress);
  123. // 读取ping命令的输出
  124. BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(),"GBK"));
  125. String line;
  126. while ((line = reader.readLine()) != null) {
  127. outputLines.add(line); // 将每行输出添加到集合中
  128. }
  129. // 等待ping命令执行完成
  130. int exitCode = process.waitFor();
  131. System.out.println("Ping命令执行完成,退出码: " + exitCode);
  132. } catch (IOException | InterruptedException e) {
  133. e.printStackTrace();
  134. }
  135. return outputLines;
  136. }
  137. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注