日期:2014-05-20 浏览次数:20833 次
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 {