All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.hugh.util.PingUtils Maven / Gradle / Ivy

There is a newer version: 2.7.14
Show newest version
package com.github.hugh.util;

import com.github.hugh.bean.dto.PingDTO;
import com.github.hugh.constant.CharsetCode;
import com.github.hugh.exception.ToolboxException;
import com.github.hugh.util.system.OsUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Ping的工具类
 *
 * @author hugh
 * @since 1.3.2
 */
public class PingUtils {
    private PingUtils() {

    }

    /**
     * 发送ping命令 并且验证ping次数是否与ping成功的次数相同
     *
     * @param ipAddress IP地址
     * @param pingCount ping次数
     * @param timeOut   超时时间毫秒
     * @return boolean {@code true}
     * @since 2.1.6
     */
    public static boolean send(String ipAddress, int pingCount, int timeOut) {
        try {
            return getConnectedCount(ipAddress, pingCount, timeOut) == pingCount;
        } catch (IOException ioException) {
            return false;
        }
    }

    /**
     * 发送ping IP 命令,验证ip
     *
     * @param ipAddress IP
     * @param pingCount ping次数
     * @param timeOut   超时时间毫秒
     * @return int  ping成功的次数
     * @since 2.1.6
     */
    public static int getConnectedCount(String ipAddress, int pingCount, int timeOut) throws IOException {
        Runtime runtime = Runtime.getRuntime();
        String pingCommand = appendCmd(ipAddress, pingCount, timeOut);
        Process process = runtime.exec(pingCommand);
        if (process == null) {
            return -1;
        }
        InputStreamReader inputStreamReader = new InputStreamReader(process.getInputStream());
        try (BufferedReader in = new BufferedReader(inputStreamReader)) {
            // 逐行检查输出,计算类似出现=23ms TTL=62字样的次数
            int connectedCount = 0;
            String line;
            while ((line = in.readLine()) != null) {
                connectedCount += getCheckResult(line);// 如果出现类似=23ms TTL=62这样的字样,出现的次数=测试次数则返回真
            }
            return connectedCount;
        }
    }

    /**
     * 若line含有=18ms TTL=16字样,说明已经ping通,返回1,否則返回0.
     *
     * @param line 字符串
     * @return int 耗时
     */
    private static int getCheckResult(String line) {
        Pattern pattern;
        if (OsUtils.isWindows()) {
            pattern = Pattern.compile("(\\d+ms)(\\s+)(TTL=\\d+)", Pattern.CASE_INSENSITIVE);
        } else {//linux例:64 bytes from 192.168.1.13: icmp_seq=0 ttl=63 time=0.641 ms 判断是否有ttl与ms
            pattern = Pattern.compile("(\\d+|\\s+ms)(\\s+)(ttl=\\d+)", Pattern.CASE_INSENSITIVE);
        }
        Matcher matcher = pattern.matcher(line);
        return matcher.find() ? 1 : 0;
    }

    /**
     * 发送多次Ping
     *
     * @param ipAddress IP地址
     * @param pingCount ping次数
     * @param timeOut   超时时间
     * @return List
     */
    public static List batch(String ipAddress, int pingCount, int timeOut) {
        List item = new ArrayList<>();
        String pingCommand = appendCmd(ipAddress, pingCount, timeOut);
        try {
            Process pro = Runtime.getRuntime().exec(pingCommand);
            BufferedReader buf = new BufferedReader(new InputStreamReader(
                    pro.getInputStream(), CharsetCode.GBK));
            String line;
            while ((line = buf.readLine()) != null) {
                if (!"".equals(line)) {//不等于空字符串时
                    item.add(line);
                }
            }
            return item;
        } catch (Exception ex) {
            throw new ToolboxException(ex);
        }
    }

    /**
     * 根据系统不通拼接对应的 ping的命令
     *
     * @param ip      IP地址
     * @param count   ping次数
     * @param timeOut 超时时间、只在windows命令中有用
     * @return String 拼接后的命令字符串
     */
    private static String appendCmd(String ip, int count, int timeOut) {
        String pingCommand;
        if (OsUtils.isWindows()) {
            pingCommand = "ping " + ip + " -n " + count + " -w " + timeOut; //此命令是windows格式的命令
        } else {
            pingCommand = "ping " + ip + " -c " + count;
        }
        return pingCommand;
    }

    /**
     * 根据ip地址发送ping 请求
     * 

注:默认发送4次ping、并且window命令下默认超时时间为10000ms

* * @param ip IP地址 * @return {@link PingDTO} * @since 1.6.4 */ public static PingDTO ping(String ip) { return ping(ip, 4, 10000); } /** * Ping * * @param ip IP地址 * @param count ping的次数 * @param timeOut 超时时间 * @return {@link PingDTO} * @since 1.6.4 */ public static PingDTO ping(String ip, int count, int timeOut) { String cmd = appendCmd(ip, count, timeOut); return send(cmd); } // /** // * 通过ip获取信息,loss:丢包率,delay:延时 // * // * @param cmd 命令 // * @return {@link PingDTO} // * @since 1.6.4 // */ // private static PingDTO send(String cmd) { // PingDTO ping = new PingDTO(); // String line; // String loss = "";//丢包率 // String delay = "";//延时 // try { // //获取当前进程运行对象 // Runtime runtime = Runtime.getRuntime(); // Process process = runtime.exec(cmd); // try (InputStream inputStream = process.getInputStream(); // InputStreamReader isReader = new InputStreamReader(inputStream, CharsetCode.GB_2312); // BufferedReader reader = new BufferedReader(isReader)) { // StringBuilder buffer = new StringBuilder(); // if (OsUtils.isWindows()) {//Windows系统执行结果解析 // while ((line = reader.readLine()) != null) { // //丢包率 // if (line.contains("%")) { // loss = line.substring(line.lastIndexOf("=") + 1, line.indexOf("%") + 1); // if (loss.contains("(")) { // loss = loss.substring(loss.indexOf("(") + 1).strip(); // } // } // //网络延时 // if ((line.contains(",") || line.contains(",")) && line.contains("=") && line.contains("ms")) { // delay = line.substring(line.lastIndexOf("=") + 1, line.lastIndexOf("ms") + 2).strip(); // } // buffer.append(line).append("\n"); // } // } else {//Linux系统执行结果解析 // while ((line = reader.readLine()) != null) { // //丢包率 // if (line.contains("%")) { // String[] msg = null; // if (line.contains(",")) { // msg = line.split(","); // } else if (line.contains(",")) { // msg = line.split(","); // } // assert msg != null; // if (msg.length > 0) { // loss = msg[2].substring(0, msg[2].indexOf("%") + 1).strip(); // } // } // //网络延时 // if (line.contains("/")) { // String[] msg = line.split("="); // String[] names = msg[0].split("/"); // String[] values = msg[1].split("/"); // for (int i = 0; i < names.length; i++) { // String str = names[i]; // if ("avg".equalsIgnoreCase(str)) { // delay = values[i]; // break; // } // } // } // buffer.append(line).append("\n"); // } // } // // 替换百分号 // loss = loss.replace("%", ""); // delay = delay.replace("ms", ""); // if (EmptyUtils.isNotEmpty(loss)) { // ping.setLoss(Integer.parseInt(loss)); // } // if (EmptyUtils.isNotEmpty(delay)) { // ping.setDelay(Double.parseDouble(delay)); // } else { // ping.setDelay(-1);// 延迟 // ping.setStatus(-1);//无法ping通 // } // } // } catch (IOException e) { // e.printStackTrace(); // ping.setStatus(-2); // } // return ping; // } /** * 发送 ping 命令并解析结果。 * * @param cmd 要执行的 ping 命令 * @return 包含解析结果的 PingDTO 对象 */ public static PingDTO send(String cmd) { PingDTO ping = new PingDTO(); try { Runtime runtime = Runtime.getRuntime(); Process process = runtime.exec(cmd); try (InputStream inputStream = process.getInputStream(); InputStreamReader isReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8); BufferedReader reader = new BufferedReader(isReader)) { String line; StringBuilder buffer = new StringBuilder(); while ((line = reader.readLine()) != null) { buffer.append(line).append("\n"); } String result = buffer.toString(); if (OsUtils.isWindows()) { parseWindowsResult(result, ping); } else { parseLinuxResult(result, ping); } } } catch (IOException ioException) { throw new ToolboxException(ioException); } return ping; } /** * 解析 Windows 系统上 ping 命令的结果。 * * @param result ping 命令的结果字符串 * @param ping 要填充解析数据的 PingDTO 对象 */ private static void parseWindowsResult(String result, PingDTO ping) { String lossPattern = "=(\\d+)%"; String delayPattern = "=\\d+ms"; Pattern lossRegex = Pattern.compile(lossPattern); Pattern delayRegex = Pattern.compile(delayPattern); Matcher lossMatcher = lossRegex.matcher(result); Matcher delayMatcher = delayRegex.matcher(result); if (lossMatcher.find()) { ping.setLoss(Integer.parseInt(lossMatcher.group(1))); } if (delayMatcher.find()) { String delay = delayMatcher.group(); delay = delay.substring(1, delay.length() - 2); ping.setDelay(Double.parseDouble(delay)); } else { ping.setDelay(-1); ping.setStatus(-1); } } /** * 解析 Linux 系统上 ping 命令的结果。 * * @param result ping 命令的结果字符串 * @param ping 要填充解析数据的 PingDTO 对象 */ private static void parseLinuxResult(String result, PingDTO ping) { String lossPattern = "\\d+\\.\\d+/%"; String delayPattern = "/(\\d+\\.\\d+)/"; Pattern lossRegex = Pattern.compile(lossPattern); Pattern delayRegex = Pattern.compile(delayPattern); Matcher lossMatcher = lossRegex.matcher(result); Matcher delayMatcher = delayRegex.matcher(result); if (lossMatcher.find()) { String loss = lossMatcher.group(); loss = loss.substring(0, loss.length() - 2); ping.setLoss((int) Double.parseDouble(loss)); } if (delayMatcher.find()) { ping.setDelay(Double.parseDouble(delayMatcher.group(1))); } else { ping.setDelay(-1); ping.setStatus(-1); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy