java关于ping方面的解惑

java在JDK1.5以前都是用java.nio包中的Ping类来实现ping。在JDK1.7版本的API文档中就没找到这个类了。

java.nio包是对非阻塞流IO进行处理,java.io包是对阻塞流IO进行处理。前几天都是使用io阻塞流来实现客户端与服务端的通信。

在socket中,目前我知道的有两个人方法可以阻塞程序,一个是输入流InputStream的read方法,一个是ServerSocket中的accept

方法。C/S模式中有个弊端,当客户端每次向服务端发送socket,服务端都会开启一个线程来管理,那么10000个客户端,服务端

就需要开启10000个线程,当客户端数量较大的时候,阻塞流IO显然不适合,那么就要使用非阻塞流IO,如果有10000个客户端,

服务端使用非阻塞IO流就只要1000个线程就可以完成管理,因为阻塞流IO是同步的,非阻塞流IO是异步的,更多的关于阻塞流IO

与非阻塞流IO的知识,我想我需要相关书籍进行学习。

那么JAVA实现ping,可以调用WINDOS系统下的命令符ping来实现。代码如下:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.UnknownHostException;

public class Test {
    public static void ping(String host){

        String line = null;
        try{
            Process pro = Runtime.getRuntime().exec("ping " + host);
            BufferedReader buf = new BufferedReader(new InputStreamReader(pro.getInputStream(),"gbk"));
            while ((line = buf.readLine()) != null){
                System.out.println(line);
            }
        }catch (Exception ex){
            System.out.println(ex.getMessage());
        }
    }

    /**
     * @param host
     */
    public static void icmp(String host){
        try {
            int timeOut = 3000;
            boolean status = InetAddress.getByName(host).isReachable(timeOut);
            System.out.println("发送数据包: " + status);
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * @param args
     */
    public static void main(String[] args) throws UnknownHostException {
        ping(InetAddress.getByName("www.baidu.com").getHostAddress());
        icmp(InetAddress.getByName("www.baidu.com").getHostAddress());
    }
}

  从代码中可以看出,我是ping了百度的,百度发回来的报文是GBK格式的,不设置会出现乱码现象,还有一个点是InetAddress包中的isReachable方法,这个方法在API文档中描述是这样的:

测试该地址是否可访问。最好的实现是通过尝试到达主机,但是防火墙和服务器配置可能会阻塞导致不可到达状态的请求,而某些特定端口可能是可访问的。一个典型的实现将使用ICMP回声请求,如果可以获得特权,否则它将试图在目标主机的端口7(回声)上建立一个TCP连接。
超时值(以毫秒为单位)表示尝试应该占用的最大时间。如果操作在获得答案之前超时,则主机被认为是不可到达的。负值将导致时抛出。

也就是说,这个方法基本上是使用目标主机的端口7建立TCP连接了,基本不关PING什么事情。

 

附上JDK1.5版本以前的Ping类实现,有兴趣的可以看看。

https://docs.oracle.com/javase/1.5.0/docs/guide/nio/example/index.html

  

posted @ 2017-12-23 17:08  PottyHarry  阅读(654)  评论(0编辑  收藏  举报