侧边栏壁纸
  • 累计撰写 781 篇文章
  • 累计创建 1 个标签
  • 累计收到 1 条评论
标签搜索

NIO

Dettan
2021-04-10 / 0 评论 / 0 点赞 / 110 阅读 / 1,794 字
温馨提示:
本文最后更新于 2022-04-30,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。
/ 后端 / Tool / NIO
原生NIO编程
两个线程,一个检测新连接,如果有就注册到读取线程上. 一个读取线程,从连接里读数据.
轮询器selector
/**
 * @author 闪电侠
 */
public class NIOServer {
    public static void main(String[] args) throws IOException {
        Selector serverSelector = Selector.open();
        Selector clientSelector = Selector.open();
    new Thread(() -> {
        try {
            // 对应IO编程中服务端启动
            ServerSocketChannel listenerChannel = ServerSocketChannel.open();
            listenerChannel.socket().bind(new InetSocketAddress(8000));
            listenerChannel.configureBlocking(false);
            listenerChannel.register(serverSelector, SelectionKey.OP_ACCEPT);

            while (true) {
                // 监测是否有新的连接,这里的1指的是阻塞的时间为1ms
                if (serverSelector.select(1) > 0) {
                    Set<SelectionKey> set = serverSelector.selectedKeys();
                    Iterator<SelectionKey> keyIterator = set.iterator();

                    while (keyIterator.hasNext()) {
                        SelectionKey key = keyIterator.next();

                        if (key.isAcceptable()) {
                            try {
                                // (1) 每来一个新连接,不需要创建一个线程,而是直接注册到clientSelector
                                SocketChannel clientChannel = ((ServerSocketChannel) key.channel()).accept();
                                clientChannel.configureBlocking(false);
                                clientChannel.register(clientSelector, SelectionKey.OP_READ);
                            } finally {
                                keyIterator.remove();
                            }
                        }

                    }
                }
            }
        } catch (IOException ignored) {
        }

    }).start();


    new Thread(() -> {
        try {
            while (true) {
                // (2) 批量轮询是否有哪些连接有数据可读,这里的1指的是阻塞的时间为1ms
                if (clientSelector.select(1) > 0) {
                    Set<SelectionKey> set = clientSelector.selectedKeys();
                    Iterator<SelectionKey> keyIterator = set.iterator();

                    while (keyIterator.hasNext()) {
                        SelectionKey key = keyIterator.next();

                        if (key.isReadable()) {
                            try {
                                SocketChannel clientChannel = (SocketChannel) key.channel();
                                ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                                // (3) 读取数据以块为单位批量读取
                                clientChannel.read(byteBuffer);
                                byteBuffer.flip();
                                System.out.println(Charset.defaultCharset().newDecoder().decode(byteBuffer)
                                        .toString());
                            } finally {
                                keyIterator.remove();
                                key.interestOps(SelectionKey.OP_READ);
                            }
                        }

                    }
                }
            }
        } catch (IOException ignored) {
        }
    }).start();


}

}

0

评论区