Java实现Ping命令

前言

在项目中有的时候需要检测两台服务器能不能正常通信,需要用到Ping命令。
目前已知的可分为两类方法:

  1. 使用Java API的InetAddress方式
  2. 使用Runtime.exec调用操作系统的命令CMD

使用InetAddress实现Ping

自Java 1.5开始,java.net包中就实现了ping的功能。详见InetAddress.isReachable()方法。

1public static boolean ping(String ipAddress) throws Exception { 2 int timeOut = 3000 ; //超时应该在3钞以上 3 boolean status = InetAddress.getByName(ipAddress).isReachable(timeOut); 4 // 当返回值是true时,说明host是可用的,false则不可。 5 return status; 6}

一般我们的应用只在内网ping的话可以使用这种方式,外网不推荐。
isReachable使用的是端口7来实现的ping命令而不是使用ICMP协议,因此在该方法在尝试连接有防火墙配置的远程服务器是会出现不可达。

调用CMD

通过程序调用类似“ping 127.0.0.1 -n 4 -w 3000”的命令,该命令ping10次,单次间隔3秒。
网络通的情况会输出:

C:\Users\tgg>ping 127.0.0.1 -n 10 -w 3000 正在 Ping 127.0.0.1 具有 32 字节的数据: 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=64 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=64 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=64 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=64 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=64 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=64 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=64 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=64 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=64 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=64 127.0.0.1 的 Ping 统计信息: 数据包: 已发送 = 10,已接收 = 10,丢失 = 0 (0% 丢失), 往返行程的估计时间(以毫秒为单位): 最短 = 0ms,最长 = 0ms,平均 = 0ms

以上信息输出是根据操作系统的语言来进行本地化的,其中"ms TTL="是不变的,我们可以通过Runtime.exec方法来调用本地CMD命令来执行以上语句,代码如下:

1import org.apache.log4j.Logger; 2import java.io.BufferedReader; 3import java.io.IOException; 4import java.io.InputStreamReader; 5import java.net.InetAddress; 6import java.util.regex.Matcher; 7import java.util.regex.Pattern; 8/** * @author tgg */ 9 10public class Ping { 11 12 public static boolean ping(String ipAddress) throws Exception { 13 int timeOut = 3000 ; 14 boolean status = InetAddress.getByName(ipAddress).isReachable(timeOut); 15 return status; 16 } 17 18 public static boolean ping(String ipAddress, int pingTimes, int timeOut) { 19 BufferedReader in = null; 20 Runtime r = Runtime.getRuntime(); 21 // 将要执行的ping命令,此命令是windows格式的命令 22 String pingCommand = "ping " + ipAddress + " -n " + pingTimes + " -w " + timeOut; 23 // Linux命令如下 24 // String pingCommand = "ping" -c " + pingTimes + " -w " + timeOut + ipAddress; 25 try { 26 if (logger.isDebugEnabled()) { 27 logger.debug(pingCommand); 28 } 29 // 执行命令并获取输出 30 Process p = r.exec(pingCommand); 31 if (p == null) { 32 return false; 33 } 34 in = new BufferedReader(new InputStreamReader(p.getInputStream())); 35 int connectedCount = 0; 36 String line; 37 // 逐行检查输出,计算类似出现=23ms TTL=62字样的次数 38 while ((line = in.readLine()) != null) { 39 connectedCount += getCheckResult(line); 40 } 41 // 如果出现类似=23ms TTL=62这样的字样,出现的次数=测试次数则返回真 42 return connectedCount == pingTimes; 43 } catch (Exception e) { 44 logger.error(e); 45 return false; 46 } finally { 47 try { 48 in.close(); 49 } catch (IOException e) { 50 logger.error(e); 51 } 52 } 53 } 54 //若line含有=18ms TTL=16字样,说明已经ping通,返回1,否則返回0. 55 private static int getCheckResult(String line) { // System.out.println("控制台输出的结果为:"+line); 56 Pattern pattern = Pattern.compile("(\\d+ms)(\\s+)(TTL=\\d+)", Pattern.CASE_INSENSITIVE); 57 Matcher matcher = pattern.matcher(line); 58 while (matcher.find()) { 59 return 1; 60 } 61 return 0; 62 } 63 64 private static final Logger logger = Logger.getLogger(Ping.class); 65}
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

Twitter的分布式自增ID算法snowflake (Java版)

概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移