在nio OP_READ和OP_WRITE操作之间进行通信

时间:2014-04-17 14:34:07

标签: java nio

我正在尝试实现基于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操作之间是否还有其他(更优化)的通信方式?

1 个答案:

答案 0 :(得分:5)

为每个接受的频道分配一个ByteBuffer,并将其保存为密钥附件,或者保存在用作密钥附件的会话对象中,也可能包含其他内容。

当OP_READ触发时,你应该阅读。不要排队等待。

NB OP_WRITE几乎总是准备好,除非套接字发送缓冲区已满。因此,当套接字缓冲区已满时,将其注册为interestOp 之外是不正确的,您可以通过write()返回零来检测。在其他任何时候,你应该在你有东西要写的时候写。如果write()返回零,则然后注册OP_WRITE(而不是OP_READ),当你得到它时,重试写:如果完成,取消注册OP_WRITE并注册OP_READ。如果你一直注册了OP_WRITE,那么选择器永远不会等待,它只会旋转。