在java NIO中使用Selector
的规范方法是:
ServerSocketChannel
事件类型注册SelectionKey.OP_ACCEPT
。select
方法(阻塞线程)OP_ACCEPT
事件,并调用相对AcceptEventHandler
接受SocketChannel
SocketChannel
事件类型注册已接受的SelectionKey.OP_READ
。ReadEventHandler
处理输入,然后使用SocketChannel
事件类型注册SelectionKey.OP_WRITE
。 我的问题是,为什么不在开始时立即注册三种事件类型?顺序是否有意义?
答案 0 :(得分:1)
在java NIO中使用
Selector
的规范方法是:
不,不是。见下文。
为什么不在开始时立即注册三种事件类型?
因为你不能。在您致电accept()
之前,您没有接受通道,并且在您注册OP_ACCEPT并将其触发之前您不会这样做,并且您无法注册接受的频道什么,直到你拥有它。
序列是否有意义?
else 没有任何意义。
注意,在您遇到短或零长度写入之前,您不会注册OP_WRITE。原因是它几乎总是准备就绪,所以策略只是在你有东西要写的时候写,并且只用OP_WRITE告诉你什么时候可以在短写之后再次写(这意味着套接字发送缓冲区是满)。
答案 1 :(得分:1)
我会尝试在对话中添加内容。
ServerSocketChannel
只能accept()
个新关联。 OP_READ
/ OP_WRITE
对你没有任何帮助。我非常确定您可以添加它们,但它们只会被忽略,因为ServerSocketChannel's
仅对accept()
远程SocketChannel
负责。
一旦accept()
获得新的SocketChannel
;你想先听OP_READ
。如果您收听OP_WRITE
,那么每次拨打OP_WRITE
时,您很可能会收到select()
,这将消耗大量资源。
当您尝试将一些数据写入OP_WRITE
并且并非所有数据都已写入时,您只想听SocketChannel
。