nio SelectionKey.OP_WRITE 的问题
2017-03-29 12:50
295 查看
SelectionKey理解(总结)
SelectKey注册了写事件,不在合适的时间去除掉,会一直触发写事件,因为写事件是代码触发的client.register(selector, SelectionKey.OP_WRITE);
或者sk.interestOps(SelectionKey.OP_WRITE)
执行了这以上任一代码都会无限触发写事件,跟读事件不同,一定注意
nio的select()的时候,只要数据通道允许写,每次select()返回的OP_WRITE都是true。所以在nio的写数据里面,我们在每次需要写数据之前把数据放到缓冲区,并且注册OP_WRITE,对selector进行wakeup(),这样这一轮select()发现有OP_WRITE之后,将缓冲区数据写入channel,清空缓冲区,并且反注册OP_WRITE,写数据完成。
这里面需要注意的是,每个SocketChannel只对应一个SelectionKey,也就是说,在上述的注册和反注册OP_WRITE的时候,不是通过channel.register()和key.cancel()做到的,而是通过key.interestOps()做到的。代码如下:
public void write(MessageSession session, ByteBuffer buffer) throws ClosedChannelException {
SelectionKey key = session.key();
if((key.interestOps() & SelectionKey.OP_WRITE) == 0) {
key.interestOps(key.interestOps() | SelectionKey.OP_WRITE);
}
try {
writebuf.put(buffer);
} catch(Exception e) {
System.out.println("want put:"+buffer.remaining()+", left:"+writebuf.remaining());
e.printStackTrace();
}
selector.wakeup();
}
.....
while(true) {
selector.select();
.....
if(key.isWritable()) {
MessageSession session = (MessageSession)key.attachment();
//System.out.println("Select a write");
synchronized(session) {
writebuf.flip();
SocketChannel channel = (SocketChannel)key.channel();
int count = channel.write(writebuf);
//System.out.println("write "+count+" bytes");
writebuf.clear();
key.interestOps(SelectionKey.OP_READ);
}
}
......
}
要点一:不推荐直接写channel,而是通过缓存和attachment传入要写的数据,改变interestOps()来写数据;
要点二:每个channel只对应一个SelectionKey,所以,只能改变interestOps(),不能register()和cancel()。
相关文章推荐
- java NIO SelectionKey.OP_READ 消息为何触发
- NIO理解通道 selector SeverSocketChannel serverSocket selectionKey
- NIO就绪处理之OP_WRITE
- NIO就绪处理之OP_WRITE
- 【Java.NIO】NIO就绪处理之OP_WRITE
- NIO SelectionKey attachment()空指针错误
- [置顶] API笔记之java.nio.channels.SelectionKey
- NIO SelectionKey中定义的4种事件
- java nio对OP_WRITE的处理解决网速慢的连接
- NIO就绪处理之OP_WRITE
- vs2005中的response.write()问题
- 在使用hashmap时遇到不同key也会覆盖的问题
- 解决AJAX中使用UpdatePanel后再用Response.Write();等无法弹出对话框问题 3法
- 如何用ReentrantReadWriteLock实现读者写者问题,且写者优先级更高
- Response.Write后css失效问题的解决
- cannot find message resources under key org.apache.struts.action.message 问题解决
- (转)解决AJAX中使用UpdatePanel后再用Response.Write();等无法弹出对话框问题 3法
- vs2005中的response.write()问题
- 解决AJAX中使用UpdatePanel后再用Response.Write();等无法弹出对话框问题
- 关于ASP.NET中用Response.Write()方法响应导致页面字体变大的问题