首页 > 代码库 > 非阻塞模式 Socket 连接

非阻塞模式 Socket 连接

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.InetAddress;import java.net.InetSocketAddress;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import java.nio.channels.SocketChannel;import java.util.Iterator;import java.util.LinkedList;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), 80);        }        catch (IOException e) {            failure = e;        }    }        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;    }}public class PingClient {    private Selector selector;    private LinkedList<Target> targets = new LinkedList<Target>();    private LinkedList<Target> finishedTargets = new LinkedList<Target>();        boolean shutdown = false;        public PingClient() throws IOException {                selector = Selector.open();        Connector connector = new Connector();        Printer printer = new Printer();        connector.start();        printer.start();        receiveTarget();            }            public static void main(String[] args) throws IOException {                new PingClient();    }            public void addTarget(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 void addFinishedTarget(Target target) {                synchronized(finishedTargets) {            finishedTargets.notify();            finishedTargets.add(target);        }    }            public void printFinishedTargets() {                try {            for(;;) {                Target target = null;                synchronized(finishedTargets) {                    while(finishedTargets.size() == 0){                        finishedTargets.wait();                    }                    target = (Target) finishedTargets.removeFirst();                }                target.show();            }        }        catch (InterruptedException e) {            return;        }    }            public void registerTargets() {                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 void processSelectedKeys() {                for(Iterator<SelectionKey> 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 void receiveTarget() {                try {            BufferedReader localReader = new BufferedReader(new InputStreamReader(System.in));            String host = null;            while((host = localReader.readLine()) != null) {                if(!host.equals("bye")) {                    Target target = new Target(host);                    addTarget(target);                }                else {                    shutdown = true;                    selector.wakeup();                    break;                }            }        }        catch (IOException e) {            e.printStackTrace();        }    }            public class Printer extends Thread {                public Printer() {            setDaemon(true);        }                public void run() {            printFinishedTargets();        }    }            public class Connector extends Thread {                public void run() {            while(! shutdown) {                try {                    registerTargets();                    if(selector.select() > 0) {                        processSelectedKeys();                    }                }                catch (Exception e) {                    e.printStackTrace();                }            }                        try {                selector.close();            }            catch (IOException e) {                e.printStackTrace();            }        }    }}

 

非阻塞模式 Socket 连接