越夜越有机 发表于 2009-2-9 09:48:09

sun官方的ping代码

sun提供的ping源码,其实是通过连接端口测试设备是否工作,与传统的ICMP实现的ping完全不同.因为icmp是链路层协议,而java是工作在三层及三层之上,java要实现icmp ping只有采用JNI来实现,当前的有jpcap,类似于winpcap,libcap的开发包.
source code:(线程同步及java.nio包中类的用法还是值得学习的).

import java.io.*;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.charset.*;
import java.util.*;
import java.util.regex.*;
public class Ping {
    // The default daytime port
    static int DAYTIME_PORT = 13;
    // The port we'll actually use
    static int port = DAYTIME_PORT;
    // Representation of a ping target
    //
    static class Target {
      InetSocketAddress address;
      SocketChannel channel;
      Exception failure;
      long connectStart;
      long connectFinish = 0;
      boolean shown = false;
      Target(String host) {
            try {
                address = new InetSocketAddress(InetAddress.getByName(host),
                        port);
            } catch (IOException x) {
                failure = x;
            }
      }
      void show() {
            String result;
            if (connectFinish != 0)
                result = Long.toString(connectFinish - connectStart)   "ms";
            else if (failure != null)
                result = failure.toString();
            else
                result = "Timed out";
            System.out.println(address   " : "   result);
            shown = true;
      }
    }
    // Thread for printing targets as they're heard from
    //
    static class Printer extends Thread {
      LinkedList pending = new LinkedList();
      Printer() {
            setName("Printer");
            setDaemon(true);
      }
      void add(Target t) {
            synchronized (pending) {
                pending.add(t);
                pending.notify();
            }
      }
      public void run() {
            try {
                for (;;) {
                  Target t = null;
                  synchronized (pending) {
                        while (pending.size() == 0)
                            pending.wait();
                        t = (Target) pending.removeFirst();
                  }
                  t.show();
                }
            } catch (InterruptedException x) {
                return;
            }
      }
    }
    // Thread for connecting to all targets in parallel via a single selector
    //
    static class Connector extends Thread {
      Selector sel;
      Printer printer;
      // List of pending targets. We use this list because if we try to
      // register a channel with the selector while the connector thread is
      // blocked in the selector then we will block.
      //
      LinkedList pending = new LinkedList();
      Connector(Printer pr) throws IOException {
            printer = pr;
            sel = Selector.open();
            setName("Connector");
      }
      // Initiate a connection sequence to the given target and add the
      // target to the pending-target list
      //
      void add(Target t) {
            SocketChannel sc = null;
            try {
                // Open the channel, set it to non-blocking, initiate connect
                sc = SocketChannel.open();
                sc.configureBlocking(false);
                boolean connected = sc.connect(t.address);
                // Record the time we started
                t.channel = sc;
                t.connectStart = System.currentTimeMillis();
                if (connected) {
                  t.connectFinish = t.connectStart;
                  sc.close();
                  printer.add(t);
                } else {
                  // Add the new channel to the pending list
                  synchronized (pending) {
                        pending.add(t);
                  }
                  // Nudge the selector so that it will process the pending
                  // list
                  sel.wakeup();
                }
            } catch (IOException x) {
                if (sc != null) {
                  try {
                        sc.close();
                  } catch (IOException xx) {
                  }
                }
                t.failure = x;
                printer.add(t);
            }
      }
      // Process any targets in the pending list
      //
      void processPendingTargets() throws IOException {
            synchronized (pending) {
                while (pending.size() > 0) {
                  Target t = (Target) pending.removeFirst();
                  try {
                        // Register the channel with the selector, indicating
                        // interest in connection completion and attaching the
                        // target object so that we can get the target back
                        // after the key is added to the selector's
                        // selected-key set
                        t.channel.register(sel, SelectionKey.OP_CONNECT, t);
                  } catch (IOException x) {
                        // Something went wrong, so close the channel and
                        // record the failure
                        t.channel.close();
                        t.failure = x;
                        printer.add(t);
                  }
                }
            }
      }
      // Process keys that have become selected
      //
      void processSelectedKeys() throws IOException {
            for (Iterator i = sel.selectedKeys().iterator(); i.hasNext();) {
                // Retrieve the next key and remove it from the set
                SelectionKey sk = (SelectionKey) i.next();
                i.remove();
                // Retrieve the target and the channel
                Target t = (Target) sk.attachment();
                SocketChannel sc = (SocketChannel) sk.channel();
                // Attempt to complete the connection sequence
                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;
      // Invoked by the main thread when it's time to shut down
      //
      void shutdown() {
            shutdown = true;
            sel.wakeup();
      }
      // Connector loop
      //
      public void run() {
            for (;;) {
                try {
                  int n = sel.select();
                  if (n > 0)
                        processSelectedKeys();
                  processPendingTargets();
                  if (shutdown) {
                        sel.close();
                        return;
                  }
                } catch (IOException x) {
                  x.printStackTrace();
                }
            }
      }
    }
    public static void main(String[] args) throws InterruptedException,
            IOException {
      //args = new String[] { "3389", "10.0.0.222" }; 测试用
      if (args.length < 1) {
            System.err.println("Usage: java Ping host...");
            return;
      }
      int firstArg = 0;
      // If the first argument is a string of digits then we take that
      // to be the port number to use
      if (Pattern.matches(" ", args)) {
            port = Integer.parseInt(args);
            firstArg = 1;
      }
      // Create the threads and start them up
      Printer printer = new Printer();
      printer.start();
      Connector connector = new Connector(printer);
      connector.start();
      // Create the targets and add them to the connector
      LinkedList targets = new LinkedList();
      for (int i = firstArg; i < args.length; i) {
            Target t = new Target(args);
            targets.add(t);
            connector.add(t);
      }
      // Wait for everything to finish
      Thread.sleep(2000);
      connector.shutdown();
      connector.join();
      // Print status of targets that have not yet been shown
      for (Iterator i = targets.iterator(); i.hasNext();) {
            Target t = (Target) i.next();
            if (!t.shown)
                t.show();
      }
    }
}
页: [1]
查看完整版本: sun官方的ping代码