首页 > 代码库 > 非阻塞模式 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 连接
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。