繁体   English   中英

一线程一ByteBuffer NIO

[英]One thread one ByteBuffer NIO

我想知道实现具有一个线程和一个缓冲区的多用户NIO服务器的最佳方法。 目前,我使用选择器来实现此目的,但我只想出了如何在所有客户端上阅读的方法。 我在使用一个缓冲区实现写入时遇到麻烦。 我需要第二个缓冲区进行写操作吗? 还是我必须(不幸地)每个客户端都有一个写缓冲区? 我写了这个示例来轻松展示我的工作方式,以便让您知道所有处理都在调度程序的线程内进行,而我不会通过另一个线程与任何状态进行交互!

ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();

ServerSocketChannel server = ServerSocketChannel.open();
Selector selector = Selector.open();
ByteBuffer buffer = ByteBuffer.allocateDirect(8192);
Map<SelectionKey, SocketChannel> clients = new HashMap<>();

server.configureBlocking(false);
server.register(selector, SelectionKey.OP_ACCEPT);
server.bind(new InetSocketAddress(43594));

scheduler.scheduleAtFixedRate(() -> {
    try {
        selector.selectNow();
        Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
        while (keys.hasNext()) {
            SelectionKey key = keys.next();
            keys.remove();
            if (key.isAcceptable()) {
                for (int i = 0; i < 16; i++) {
                    SocketChannel client = server.accept();
                    if (client == null)
                        break;
                    client.configureBlocking(false);
                    SelectionKey clientKey = client.register(selector, SelectionKey.OP_READ);
                    clients.put(clientKey, client);
                }
            }
            if (key.isReadable()) {
                SocketChannel client = clients.get(key);
                if (client != null) {
                    buffer.clear();
                    client.read(buffer);
                    buffer.flip();
                    // do stuff with buffer
                }
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}, 600, 600, TimeUnit.MILLISECONDS);

你不能 对于比回显服务器更简单的事情,每个通道至少需要一个缓冲区,可能需要两个(读和写)。 否则,您将无法处理部分读取的请求或部分写入的响应。

您可以通过SelectionKey附件将缓冲区与通道关联。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM