zoukankan      html  css  js  c++  java
  • 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()。

  • 相关阅读:
    hadoop项目放在tomcat服务器中遇见的问题
    hadoop-hdfs间文件复制
    fastdfs扩容
    mysql-8.0修改密码方式
    同一个服务器启动两个redis服务记录!
    springboot+vue完美跨域 解决sessionId不一致问题
    docker 拉取fastDFS镜像
    共享锁、排他锁、互斥锁、悲观锁、乐观锁、行锁、表锁、页面锁、不可重复读、丢失修改、读脏数据
    linux下后台运行node-js项目
    概念解释:分组密码、流密码、对称密码、非对称密码
  • 原文地址:https://www.cnblogs.com/burgeen/p/3618059.html
Copyright © 2011-2022 走看看