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

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

The newest version!
package com.github.hugh.util;

import com.github.hugh.constant.CharsetCode;
import com.github.hugh.model.dto.PingDTO;
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.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 IP是否能够正常访问
     *
     * @param ipAddress IP地址
     * @param pingCount ping次数
     * @param timeOut   超时时间毫秒
     * @return boolean {@code true}
     */
    public static boolean send(String ipAddress, int pingCount, int timeOut) {
        Runtime runtime = Runtime.getRuntime();
        String pingCommand = appendCmd(ipAddress, pingCount, timeOut);
        try { // 执行命令并获取输出
            Process process = runtime.exec(pingCommand);
            if (process == null) {
                return false;
            }
            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 == pingCount;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            return false;// 出现异常则返回false
        }
    }

    /**
     * 若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 strs = 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)) {//不等于空字符串时
                    strs.add(line);
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return strs;
    }

    /**
     * 根据系统不通拼接对应的 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; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy