importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStreamReader;importjava.net.InetAddress;importjava.net.InetSocketAddress;importjava.nio.channels.SelectionKey;importjava.nio.channels.Selector;importjava.nio.channels.SocketChannel;importjava.util.Iterator;importjava.util.LinkedList;classTarget {
InetSocketAddress address;
SocketChannel channel;
Exception failure;longconnectStart;long connectFinish = 0;boolean shown = false;
Target(String host) {try{
address= new InetSocketAddress(InetAddress.getByName(host), 80);
}catch(IOException e) {
failure=e;
}
}voidshow() {
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;
}
}public classPingClient {privateSelector selector;private LinkedList targets = new LinkedList();private LinkedList finishedTargets = new LinkedList();boolean shutdown = false;public PingClient() throwsIOException {
selector=Selector.open();
Connector connector= newConnector();
Printer printer= newPrinter();
connector.start();
printer.start();
receiveTarget();
}public static void main(String[] args) throwsIOException {newPingClient();
}public voidaddTarget(Target target) {
SocketChannel socketChannel= null;try{
socketChannel=SocketChannel.open();
socketChannel.configureBlocking(false);
socketChannel.connect(target.address);
target.channel=socketChannel;
target.connectStart=System.currentTimeMillis();synchronized(targets) {
targets.add(target);
}
selector.wakeup();
}catch(Exception e) {if(socketChannel != null) {try{
socketChannel.close();
}catch(IOException ex) {
}
}
target.failure=e;
addFinishedTarget(target);
}
}public voidaddFinishedTarget(Target target) {synchronized(finishedTargets) {
finishedTargets.notify();
finishedTargets.add(target);
}
}public voidprintFinishedTargets() {try{for(;;) {
Target target= null;synchronized(finishedTargets) {while(finishedTargets.size() == 0){
finishedTargets.wait();
}
target=(Target) finishedTargets.removeFirst();
}
target.show();
}
}catch(InterruptedException e) {return;
}
}public voidregisterTargets() {synchronized(targets) {while(targets.size() > 0) {
Target target=(Target) targets.removeFirst();try{
target.channel.register(selector, SelectionKey.OP_CONNECT, target);
}catch(IOException e) {try{
target.channel.close();
}catch(IOException ex) {
ex.printStackTrace();
}
target.failure=e;
addFinishedTarget(target);
}
}
}
}public voidprocessSelectedKeys() {for(Iterator it =selector.selectedKeys().iterator(); it.hasNext();) {
SelectionKey selectionKey=it.next();
it.remove();
Target target=(Target) selectionKey.attachment();
SocketChannel socketChannel=(SocketChannel) selectionKey.channel();try{if(socketChannel.finishConnect()) {
selectionKey.cancel();
target.connectFinish=System.currentTimeMillis();
socketChannel.close();
addFinishedTarget(target);
}
}catch(IOException e) {try{
socketChannel.close();
}catch(IOException ex) {
ex.printStackTrace();
}
target.failure=e;
addFinishedTarget(target);
}
}
}public voidreceiveTarget() {try{
BufferedReader localReader= new BufferedReader(newInputStreamReader(System.in));
String host= null;while((host = localReader.readLine()) != null) {if(!host.equals("bye")) {
Target target= newTarget(host);
addTarget(target);
}else{
shutdown= true;
selector.wakeup();break;
}
}
}catch(IOException e) {
e.printStackTrace();
}
}public class Printer extendsThread {publicPrinter() {
setDaemon(true);
}public voidrun() {
printFinishedTargets();
}
}public class Connector extendsThread {public voidrun() {while(!shutdown) {try{
registerTargets();if(selector.select() > 0) {
processSelectedKeys();
}
}catch(Exception e) {
e.printStackTrace();
}
}try{
selector.close();
}catch(IOException e) {
e.printStackTrace();
}
}
}
}