(三)JAVA NIO SELECTOR

6

Selector(选择器)是Java NIO中能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件。这样,一个单独的线程可以管理多个channel,从而管理多个网络连接。

SelectServer.java

public class SelectServer {
    public static void main(String[] args) throws IOException {
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.socket().bind(new InetSocketAddress(9999));
        serverSocketChannel.configureBlocking(false);
        Selector selector = Selector.open();
        SelectionKey selectionKey = serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        while (true) {
            int select = selector.select();
            if (select > 0) {
                Iterator keyIterator = selector.selectedKeys().iterator();
                while (keyIterator.hasNext()) {
                    SelectionKey next = (SelectionKey) keyIterator.next();
                    keyIterator.remove();
                    if (next.isAcceptable()) {
                        System.out.println("isAcceptable");
                        SocketChannel channel = ((ServerSocketChannel) next.channel()).accept();
                        channel.configureBlocking(false);
                        channel.register(selector, SelectionKey.OP_READ);
                    } else if (next.isConnectable()) {
                        System.out.println("connect");
                    } else if (next.isReadable()) {
                        System.out.println("isReadable");
                        SocketChannel socketChannel = (SocketChannel) next.channel();
                        ByteBuffer readByteBuffer = ByteBuffer.allocate(100);
                        int read = socketChannel.read(readByteBuffer);
                        System.out.println(new String(readByteBuffer.array(), 0, read));
                        socketChannel.register(selector, SelectionKey.OP_WRITE);
                        socketChannel.write(readByteBuffer);
                    } else if (next.isWritable()) {
                        System.out.println("isWritable");
                        SocketChannel socketChannel = (SocketChannel) next.channel();
                        socketChannel.register(selector, SelectionKey.OP_READ);
                    }
                }
            }
        }
    }
}

NioChannelClient.java

public class NioChannelClient {
    public static void main(String[] args) throws IOException {
        SocketChannel socketChannel = SocketChannel.open();
        socketChannel.connect(new InetSocketAddress("localhost", 9999));
        while (true) {
            Scanner input = new Scanner(System.in);
            socketChannel.write(ByteBuffer.wrap(input.nextLine().getBytes()));
        }
    }
}

Nio源码地址​github.com