NIO – Selector代码示例

package player.kent.chen.temp.learnnio.selector;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

public class PlaySelector {

    public static void main(String[] args) throws IOException, InterruptedException {
        ServerSocketChannel serverChannel = ServerSocketChannel.open();
        serverChannel.socket().bind(new InetSocketAddress(17547));
        serverChannel.configureBlocking(false);

        Selector selector = Selector.open();//这个selector将同时用于serverChannel和accept()后针对单个连接的socketChannel
        serverChannel.register(selector, SelectionKey.OP_ACCEPT); //侦听ACCEPT就绪事件

        System.out.println("开始侦听连接...");
        while (true) {
            int n = selector.select(); //阻塞直到有事件发生

            if (n == 0) { //这代表selector被别的线程惊醒,不代表任何就绪事件
                continue;
            }

            Iterator<SelectionKey> it = selector.selectedKeys().iterator();
            while (it.hasNext()) {

                SelectionKey key = it.next();
                if (key.isAcceptable()) {
                    System.out.println("serverChannel上有新连接了");
                    SocketChannel socketChannel = ((ServerSocketChannel) key.channel()).accept();
                    //为针对单个连接的socketChannel注册“读就绪”key
                    if (socketChannel != null) { //真有可能为null
                        socketChannel.configureBlocking(false);
                        socketChannel.register(selector, SelectionKey.OP_READ); //还用那个selector
                        socketChannel.write(ByteBuffer.wrap(("Hi, man\n").getBytes())); //问候客户端
                    }
                }

                if (key.isReadable()) {
                    System.out.println("针对某个连接的socketChannel可读了");
                    SocketChannel socketChannel = (SocketChannel) key.channel();
                    if (socketChannel != null) {
                        //读取输入后关闭socket
                        ByteBuffer inputBuffer = ByteBuffer.allocate(10);
                        socketChannel.read(inputBuffer);
                        inputBuffer.flip();
                        String strRead = new String(inputBuffer.array());
                        System.out.println("The user has input: " + strRead);
                        socketChannel.close();
                    }
                }

                it.remove();

            }

        }
    }
}


Leave a Comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.