异步I/O是没有阻塞地读写数据的方法。通常在代码进行read调用时,代码会阻塞直至可供读取的数据。同样,write调用将会阻塞直至数据能够写入。

1、selector是一个对象,可以注册到很多个channel上,监听各个channel上发生的事件,并且能够根据事件情况决定channel读写,这样通过一个线程管理多个channel

创建selector:

Selector selector = Selector.open();

注册channel到selector:

channel.configureBlocking(false);

SelectionKey key = chanenl.register(selector, SelecltionKey.OP_READ_;

注意,注册channel必须设置为异步模式才可以。register调用的返回值是selectionKey。这个对象待办这个通道在此selector上的这个注册。当某个selector

通知你某个传入事件时,它是通过提高对应于该事件的SelectionKey来进行的。selectionKey还可以用于取消通过的注册

2、channel和selector

Channel channel = selectionKey.channel();

Selector selector = selectioKey.selector();

demo:

public class MultiPortEcho {

  private int ports[];

  private ByteBuffer echoBuffer = ByteBuffer.allocate(1024);

  public MultiPortEcho(int ports[]) throws IOException {

  this.ports = ports;

  go();

}

private void go() throws IOException {

  //create selector

  Selector selector = Selector.open();

  //为每个端口打开一个监听,并把这些监听注册到selector中

  for(int i = 0; i < ports.length; ++i) {

    //打开一个serverSocketChannel

    ServerSocketChannel ssc = ServerSocketChnanel.open();

    ssc.configureBlocking(false);//设置为非阻塞

    ServerSocket ss = ssc.socket();

    InetSocketAddress address = new InetSocketAddress(ports[i]);

    ss.bind(address); //监听一个端口

    //注册到selector

    SelectionKey key = ssc.register(selector, SelectionKey.OP_ACCEPT);

    System.out.println("going to listen to " + ports[i]);

  }

  while(true) {

    int num = selector.select();//返回所发生的事件的数量

    Set selectedKeys = selector.selectKeys();

    Iterator it = selectedKeys.iterator();

    while(it.hasNext()) {

      SelectionKey key = (SelectionKey)it.next();

      //监听新连接,调用readops方法,检查发生了什么类型的事件

      if((key.readyOps() & selectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) {

        //接受一个新连接

        ServerSocketChannel ssc = (ServerSocketChannel) key.channel();

        SocketChannel sc = ssc.accept();

        sc.configureBlocking(false);

        //将新连接注册到selector。

        SelectionKey newKey = sc.register(selector, SelectionKey.OP_READ);

        it.remove();

        System.out.println("got connection from " + sc);

      }else if( (key.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) {

          SocketChannel sc = (SocketChannel)key.channel();

          int bytesEchoed = 0;

          while(true) {

            echoBuffer.clear();

            int r = sc.read(echoBuffer);

            if( r <= 0 ) {

            break;

          }

          echoBuffer.flip();

          sc.write(echoBuffer);

          bytesEchoed += r;

        }

        System.out.println("echoed" + bytesEchoed + "from" + sc);

        it.remove();

        // System.out.println( "going to clear" ); // selectedKeys.clear(); // System.out.println( "cleared" );

      }

    }

    static public void main(String args2[]) throws Exception {

      String args[]={"9001","9002","9003"};

       if (args.length <= 0) {

        System.err.println("Usage: java MultiPortEcho port [port port ...]");

        System.exit(1);

       }

      int ports[] = new int[args.length];

      for (int i = 0; i < args.length; ++i) {

        ports[i] = Integer.parseInt(args[i]);

      }

      new MultiPortEcho(ports);

    }

  }

  }

}

最新文章

  1. Yii 2.x RESTful 应用 - 类图
  2. 基础3.Jquery操作Dom
  3. ThreadLocal用法和实现原理
  4. Nginx使用webbench进行压力测试
  5. iOS WKWebView详解
  6. 112. Path Sum
  7. SQL Server数据库学习笔记-外键
  8. NOIP2009 最优贸易
  9. alpha-咸鱼冲刺day6-紫仪
  10. Paper Read: Convolutional Image Captioning
  11. git之sourceTree操作流程
  12. Oracle 学习笔记 (七)
  13. python3 与 Django 连接数据库报错:ImportError: No module named &#39;MySQLdb&#39;
  14. gcc和gdb使用笔记
  15. Coding in Delphi(前4章翻译版本) (PDF)
  16. http 本地服务器设置任意IP访问对应的文件夹
  17. 微信小程序初体验与DEMO分享
  18. Ubuntu环境变量解析
  19. 软工网络15团队作业8——Beta阶段敏捷冲刺(用户使用调查报告)
  20. 解决Win7&amp;Win8 64位下Source Insight提示未完整安装的问题[转]

热门文章

  1. 【归纳】Layui table.render里的json后台传入
  2. Codeforces Round #518 (Div. 1) Computer Game 倍增+矩阵快速幂
  3. 数组之间的比较应当用Arrays.equals()
  4. 常用jstl
  5. 【leetcode】905. Sort Array By Parity
  6. Java反射学习-4 - 反射调用方法
  7. ECS运维:操作系统有异常?诊断日志来帮忙!
  8. linux0.11内核源码——boot和setup部分
  9. flask-路转换器
  10. Java学习之包