我正在尝试实现基于 java.nio Selector 的 http 服务器(为了好玩)。在 key.isReadable()
上,我正在读取这样的数据:
ByteBuffer buf = ByteBuffer.allocate(4096);
SocketChannel client = (SocketChannel) key.channel();
//Gathering whole client request
((ByteBufferQueue) key.attachment()).enqueue(buf);
key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
请查看收集客户的请求。在 OP_READ 操作期间在某种队列中收集 ByteBuffers 是一种常见的做法吗?在 OP_READ 和 OP_WRITE 操作之间是否有任何其他(更优化的)通信方式?
最佳答案
为每个接受的 channel 分配一个 ByteBuffer,并将其保存为 key 附件,或者保存在用作 key 附件的 session 对象中,该对象可能还包含其他内容。
当 OP_READ 触发时,您应该阅读。不要在排队的事情上胡思乱想。
NB OP_WRITE 几乎总是准备就绪,除非套接字发送缓冲区已满。因此,当套接字缓冲区已满时将其注册为 interestOp except 是不正确的,您可以通过返回零的 write() 检测到这一点。在所有其他时间,您应该只在有东西要写时才写。如果 write() 返回零,然后注册 OP_WRITE(而不是 OP_READ),当你得到它时,重试写入:如果它完成,注销 OP_WRITE 并注册 OP_READ。如果您一直注册 OP_WRITE,选择器将永远不会等待,它只会旋转。
关于java - nio OP_READ 和 OP_WRITE 操作之间的通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23136079/