java实现ping命令

 

 

通过InetSocketAddress InetAddress 确定目标主机,Selector选择器 SelectionKey可选择通道到选择器的注册 SocketChannel对面向流的连接套接字的可选择通道 。从开始连接计时,到连接完成停止,如果连接成功返回连接所消耗的时间,否则返回timeout,若果连接过程中出现错误,怎返回该错误。

 

package com.xie.test;

import java.awt.Button;
import java.awt.Frame;
import java.awt.Label;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.*;
import java.net.*;
import java.nio.channels.*;
import java.util.*;
import java.util.regex.*;

 

public class Ping extends Frame{
 
 Label label1;
 TextField tf0;
 TextArea tf1;
 Button btnSend,btnClear;
 String to;
    //默认连接端口
    static int DAYTIME_PORT = 80;

    // 实际应用的连接端口
    static int port = DAYTIME_PORT;

    Ping(){
     setTitle("ping的java实现");
     setLayout(null);
     setBounds(400, 400, 320, 240);
     label1=new Label("请输入ping的地址:");
     label1.setBounds(0, 40, 100, 20);
     tf0=new TextField("www.baidu.com");
     to=tf0.getText();
     tf0.setBounds(100, 40, 120, 20);
     tf1=new TextArea(5, 1);
     tf1.setBounds(0, 60, 320, 160);
     btnSend=new Button("ping");
     btnSend.setBounds(280, 220, 40, 20);
     btnSend.addActionListener(new PingSend());
     btnClear=new Button("清空");
     btnClear.addActionListener(new ClearPing());
     btnClear.setBounds(250, 40, 40, 20);
     add(label1);
     add(tf0);
     add(btnSend);
     add(btnClear);
     add(tf1);
     
     addWindowListener(new WindowAdapter() {

   @Override
   public void windowClosing(WindowEvent e) {
                  System.exit(0);
   }
  });
     setResizable(false);
     setVisible(true);
    }
/**
 * 准备要ping的目标主机
 * @author centre
 */
   class Target {

 InetSocketAddress address;
 SocketChannel channel;
 String host;
 Exception failure;
 long connectStart;
 long connectFinish = 0;
 boolean shown = false;

 Target(String host) {
  this.host=host;
  String m="^[w]{3}//.//w*//..*";
  String m1="(^http://)([w]{3}//.//w*//..*)";
  String m2="//d{1,3}//.//d{1,3}//.//d{1,3}//.//d{1,3}";
  Pattern p=Pattern.compile(m);
  Pattern p1=Pattern.compile(m1);
  Pattern p2=Pattern.compile(m2);
  Matcher m01=p.matcher(host);
  Matcher m02=p1.matcher(host);
  Matcher m03=p2.matcher(host);
     try {
      if (m01.find()) {
    //System.out.println("ping-> "+host);
    address = new InetSocketAddress(InetAddress.getByName(host),port);
    }else if (m02.find()) {
    //System.out.println("ping-> "+host);
    
    address = new InetSocketAddress(InetAddress.getByName(m02.group(2)),port);
   }else if(m03.find()){
    //System.out.println("ping-> "+host);
    address = new InetSocketAddress(host,port);
   }
       
        } catch (IOException x) {
         failure = x;
          }
    }
/**
 * 显示连接主机的相关信息,如连接时间,出错提示。
 * @author centre
 */
 void show() {
  String m2="//d{1,3}//.//d{1,3}//.//d{1,3}//.//d{1,3}";
  Pattern p2=Pattern.compile(m2);
  Matcher m03=p2.matcher(host);
     String result;
     if (tf1.getText()!="") {
      tf1.setText(tf1.getText()+"/n"+"ping->"+host);
  }else {
   tf1.setText("ping->"+host);
  }
    
     if (connectFinish != 0)
  result = Long.toString(connectFinish - connectStart) + "ms";
     else if (failure != null)
  result = failure.toString();
     else
  result = "Timed out";
     for(int i=0;i<4;i++){
      if (m03.find()) {
       tf1.setText(tf1.getText()+"/n"+address.getHostName()+"/"+address + " : " + result);
       //System.out.println(address.getHostName()+"/"+address + " : " + result);
       
   }else {
    tf1.setText(tf1.getText()+"/n"+address + " : " + result);
    //System.out.println(address + " : " + result);
   }
     }
    
    
     shown = true;
 }
  
}


/**
 * 打印目标主机线程监听到的信息
 * @author centre
 *
 */
    class Printer extends Thread {
   LinkedList<Target> pinging = new LinkedList<Target>();
      Printer() {
       setName("Printer");//改变线程名字,使之与参数相同
       setDaemon(true);//标志该线程为守护线程
 }

 void add(Target t) {
      synchronized (pinging) {
   pinging.add(t);
   pinging.notify();
     }
 }

 public void run() {
     try {
   for (;;) {
       Target t = null;
       synchronized (pinging) {
       while (pinging.size() == 0)
              pinging.wait();
              t = (Target)pinging.removeFirst();//从pinging中移除目标主机,并将该目标主机返回
       }
       t.show();
   }
   } catch (InterruptedException x) {
        return;
     }
 }
}

    // 通过单选择方式连接并行的目标主机线程
    class Connector extends Thread{
  Selector sel;
  Printer printer;
  /*
   *pinging目标的集合 ,我们用这个集合是因为如果我们要用一个selector来注册一个channel
   *当connector线程在selector中被阻塞,那么我们可以阻塞它。
   */ 
  LinkedList<Target> pinging = new LinkedList<Target>();
     Connector(Printer pr) throws IOException {
      printer = pr;
      sel = Selector.open();
      setName("Connector");
  }
     //初始化一个Connection序列给指定的target,同时把该target加到pinging目标集合
  void add(Target t) {
      SocketChannel sc = null;
      try {
        //打开一个频道,把它设置为非阻塞的,同时初始化连接
   sc = SocketChannel.open();
   
   sc.configureBlocking(false);
   boolean connected = sc.connect(t.address);
   
   
 
   //记录开始连接时的时间
   t.channel = sc;
   t.connectStart = System.currentTimeMillis();
 
   if (connected) {
    
       t.connectFinish = t.connectStart;
       sc.close();
       printer.add(t);
   } else {
    //如果为连接,则把新的channel加入到pinging集合
       synchronized (pinging) {
           pinging.add(t);
       }
   }
 
       // 使尚未返回的第一个选择操作立即返回
       sel.wakeup();
      }catch (IOException x) {
   if (sc != null) {
       try {
    sc.close();
       } catch (IOException e) {
        e.printStackTrace();
       }
   }
   t.failure = x;
   printer.add(t);
      }
 }

 // 处理任何在pinging集合中的目标
 void processpingingTargets() throws IOException {
     synchronized (pinging) {
  while (pinging.size() > 0) {
      Target t = (Target)pinging.removeFirst();//取出第一个目标
      try {
            /*向给定的选择器注册此通道,返回一个选择键
             */
   t.channel.register(sel, SelectionKey.OP_CONNECT, t);

      } catch (IOException x) {
       
      //如果发生异常,将channel关闭,同时记录异常。
   t.channel.close();
   t.failure = x;
   printer.add(t);

      }

  }
     }
 }
     //处理选择的key
 void processSelectedKeys() throws IOException {
     for (Iterator i = sel.selectedKeys().iterator(); i.hasNext();) {

  // 索引下一个key,同时将其从set中移除。
  SelectionKey sk = (SelectionKey)i.next();
  i.remove();
  // 找到目标和channel
  Target t = (Target)sk.attachment();
  SocketChannel sc = (SocketChannel)sk.channel();
  
  // 试图完成连接序列
  try {
      if (sc.finishConnect()) {
   sk.cancel();
   t.connectFinish = System.currentTimeMillis();
   sc.close();
   printer.add(t);
      }
  } catch (IOException x) {
      sc.close();
      t.failure = x;
      printer.add(t);
  }
     }
 }

 volatile boolean shutdown = false;

 // 当target线程关闭时,调用主线程
 void shutdown() {
     shutdown = true;
     sel.wakeup();
 }

   //循环连接
 public void run() {
     for (;;) {
  try {
      int n = sel.select();
      if (n > 0)
           processSelectedKeys();
              processpingingTargets();

      if (shutdown) {
   sel.close();
   return;
      }
  } catch (IOException x) {
      x.printStackTrace();
  }
     }
 }

    }

    class ClearPing implements ActionListener{

  @Override
  public void actionPerformed(ActionEvent e) {
               tf0.setText("");   
  }
     
    }
    class PingSend implements ActionListener{

  @Override
  public void actionPerformed(ActionEvent e) {
   if (to!="") {
    to=tf0.getText();
   }
   // 创建线程同时将它们启动
   Printer printer = new Printer();
   printer.start();
   
   Connector connector = null;
   try {
    connector = new Connector(printer);
   } catch (IOException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
   }

   connector.start();
  
   // 创建目标,同时把它们加入集合
   LinkedList<Target> targets = new LinkedList<Target>();
     for(int i=0;i<1;i++){
       Target t = new Target(to);
      
       targets.add(t);
       connector.add(t);
     }
 
  
   // 等待结束
    try {
     Thread.sleep(2000);
    } catch (InterruptedException e1) {
     // TODO Auto-generated catch block
     e1.printStackTrace();
    }

   connector.shutdown();

   try {
    connector.join();
   } catch (InterruptedException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
   }
  
   // 打印目标没显示的状态
   for (Iterator i = targets.iterator(); i.hasNext();) {
       Target t = (Target)i.next();
       while(!t.shown)
    t.show();
       t.shown = true;
   }
  }
     
    }
    public  static void  main(String[] args)throws InterruptedException, IOException{
     
         Ping p=new Ping();
         if (p.to=="") {
    p.to="www.baidu.com";
    p.tf0.setText(p.to);
   }
         port=80;


    }

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值