Java实现Windows平台下Ping的最佳方法
2014-01-18 20:09
696 查看
先上结论:通过调用系统自带的Ping命令来实现,使用exitValue()值来判断Ping的结果。按照惯例,0表示ok,1表示不通。
解析:
1.Ping就是一个exe,因此命令中无需加上cmd;测试发现,前面加了cmd与cmd /k 效果一样,Ping执行完毕后cmd进程并不会自动结束,导致java程序无法自动结束;
2.对于Ping结果的判断,测试发现无法像批处理一样通过读取系统的errorlevel来实现。首先该值既不是系统环境变量,也不是系统属性,无法通过java内置的函数来获取;只能将"echo %errorlevel%"作为一条cmd命令,当然前面还要加上“cmd /c”的前缀;测试中发现,无论Ping通与否,程序读取到的errorlevel值都为0.
网上给出的其他方法分析
1.isReachable(int timeout)
乍一看这个方法真方便,实际上该方法在windows平台下不太实用。首先,在Win7 64位系统下测试结果:对任何主机均返回false。 javadoc写道,如果能够获得特权,它将使用ICMP来实现,否则使用TCP端口7(注:echo)来实现。然而windows主机一般是不会开启该端口的。搜索到有一老外的Blog说在linux下通过配置java虚拟机来让其获得权限从而使用ICMP,他也表示不知道在windows下如何解决。还看到一个Blog上写道将timeout设置到非常大的数字可保证准确的结果,然而我实测无效。
2.有人提到了一个实现了Ping.Class的NIO:http://docs.oracle.com/javase/1.5.0/docs/guide/nio/example/Ping.java
查看源码发现它是通过Socket连接目标的13端口,那么很明显该方法也不行。
3.使用Socket构造ICMP报文
这个应该是可行的,只不过基本上就是一个堆积字节数组的过程,比较麻烦。因此这显然不是最佳方案啦~
private static void pingTest1() throws Exception { String[] ipStrings = { "127.0.0.1", "10.0.0.1", "8.8.8.8", "10.0.0.2", "114.114.114.114", "114.114.114.11", "114.114.114.114"}; String line = null; for (String ip : ipStrings) { Process pro = Runtime.getRuntime().exec("ping " + ip + " -n 1 -w 50"); BufferedReader buf = new BufferedReader(new InputStreamReader(pro.getInputStream())); while((line = buf.readLine()) != null) System.out.println(line); pro.waitFor(); System.out.println(ip + " : " + pro.exitValue()); } }
解析:
1.Ping就是一个exe,因此命令中无需加上cmd;测试发现,前面加了cmd与cmd /k 效果一样,Ping执行完毕后cmd进程并不会自动结束,导致java程序无法自动结束;
2.对于Ping结果的判断,测试发现无法像批处理一样通过读取系统的errorlevel来实现。首先该值既不是系统环境变量,也不是系统属性,无法通过java内置的函数来获取;只能将"echo %errorlevel%"作为一条cmd命令,当然前面还要加上“cmd /c”的前缀;测试中发现,无论Ping通与否,程序读取到的errorlevel值都为0.
网上给出的其他方法分析
1.isReachable(int timeout)
乍一看这个方法真方便,实际上该方法在windows平台下不太实用。首先,在Win7 64位系统下测试结果:对任何主机均返回false。 javadoc写道,如果能够获得特权,它将使用ICMP来实现,否则使用TCP端口7(注:echo)来实现。然而windows主机一般是不会开启该端口的。搜索到有一老外的Blog说在linux下通过配置java虚拟机来让其获得权限从而使用ICMP,他也表示不知道在windows下如何解决。还看到一个Blog上写道将timeout设置到非常大的数字可保证准确的结果,然而我实测无效。
2.有人提到了一个实现了Ping.Class的NIO:http://docs.oracle.com/javase/1.5.0/docs/guide/nio/example/Ping.java
查看源码发现它是通过Socket连接目标的13端口,那么很明显该方法也不行。
3.使用Socket构造ICMP报文
这个应该是可行的,只不过基本上就是一个堆积字节数组的过程,比较麻烦。因此这显然不是最佳方案啦~
相关文章推荐
- Java实现ping功能的三种方法--windows(版本)---linux下请自行修改 【ping】参数 跟 正则验证
- JAVA用JNI方法调用C代码实现HelloWorld(含windows及ubuntu两种操作系统环境下的操作)
- java实现ping功能的几种方法
- Windows 平台上的使用 Java 语言实现 appium 自动化程序 for Android(完整版)
- 在 Windows 中实现 Java 本地方法
- Java实现ping功能的三种方法
- Windows平台实现PHP连接SQL Server2008的方法
- Java实现ping功能的三种方法
- 在 Windows上实现Java7 和Java8 并存(可随意切换) 的方法
- 在 Windows 中实现 Java 本地方法
- Java实现ping功能的三种方法
- 在 Windows 中实现 Java 本地方法
- Appium :Windows 平台上的使用 Java 语言实现 appium 自动化程序 for Android
- .NET编译项目时出现《此实现不是 Windows 平台 FIPS 验证的加密算法的一部分》处理方法
- Windows 平台上的使用 Java 语言实现 appium 自动化程序 for Android(完整版)
- 最简单方法:windows平台下python安装opencv,即实现import cv2功能
- JAVA分别实现Windows平台和Linux平台下的ip获取
- Java实现ping功能的三种方法
- 一种在windows平台下实现自动操作应用的方法,附带源码地址及使用方法