异步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);

    }

  }

  }

}

网络编程NIO-异步的更多相关文章

  1. Java网络编程中异步编程的理解

    目录 前言 一.异步,同步,阻塞和非阻塞的理解 二.异步编程从用户层面和框架层面不同角度的理解 用户角度的理解 框架角度的理解 三.为什么使用异步 四.理解这些能在实际中的应用 六.困惑 参考文章 前 ...

  2. Java网络编程 -- NIO非阻塞网络编程

    从Java1.4开始,为了替代Java IO和网络相关的API,提高程序的运行速度,Java提供了新的IO操作非阻塞的API即Java NIO.NIO中有三大核心组件:Buffer(缓冲区),Chan ...

  3. 网络编程之异步IO,rabbitMQ笔记

    对于网络并发编程而言,多线程与多进程算是最常见的需求场景了.毕竟网站开放就是想要更多的流量访问的. 回顾 回顾下之前学过的关于线程,进程和协程的知识点 IO密集型任务--用多线程更好计算密集型任务-- ...

  4. 网络编程NIO:BIO和NIO

    BIO BIO(Blocking I/O),同步阻塞,实现模式为一个连接一个线程,即当有客户端连接时,服务器端需为其单独分配一个线程,如果该连接不做任何操作就会造成不必要的线程开销.BIO是传统的Ja ...

  5. iOS网络编程(三) 异步加载及缓存图片---->SDWebImage

    @SDWebImage提供一个UIImageView的类别以支持加载来自网络的远程图片.具有缓存管理.异步下载.同一个URL下载次数控制和优化等特征. @SDWebImage的导入1.https:// ...

  6. Java网络编程 -- AIO异步网络编程

    AIO中的A即Asynchronous,AIO即异步IO.它是异步非阻塞的,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理,一般我们的业务处理逻辑会变成一个回调函数,等待IO操 ...

  7. 原生JDK网络编程- NIO之Reactor模式

    “反应”器名字中”反应“的由来: “反应”即“倒置”,“控制逆转”,具体事件处理程序不调用反应器,而向反应器注册一个事件处理器,表示自己对某些事件感兴趣,有时间来了,具体事件处理程序通过事件处理器对某 ...

  8. 原生JDK网络编程- NIO

    什么是NIO? NIO 库是在 JDK 1.4 中引入的.NIO 弥补了原来的 I/O 的不足,它在标准 Java 代码中提供了高速的.面向块的 I/O.NIO翻译成 no-blocking io 或 ...

  9. 网络编程之异步IO

    Linux的I/O模型有下面几种:1. 同步阻塞I/O: 用户进程进行I/O操作,一直阻塞到I/O操作完成为止.2. 同步非阻塞I/O: 用户程序可以通过设置文件描述符的属性O_NONBLOCK,I/ ...

  10. 网络编程NIO之Reactor线程模型

    目录 单Reactor线程模型 基于工作线程的Reactor线程模型 多Reactor线程模型 多Reactor线程模型示例 结束语 上篇文章中写了一些NIO相关的知识以及简单的NIO实现示例,但是示 ...

随机推荐

  1. Windows 搭建MongoDB分片集群(二)

    在本篇博客中我们主要讲描述分片集群的搭建过程.配置分片集群主要有两个步骤,第一启动所有需要的mongod和mongos进程.第二步就是启动一个mongos与集群通信.下面我们一步步来描述集群的搭建过程 ...

  2. ThinkPHP import 类库导入 include PHP文件

    ThinkPHP 模拟了 Java 的类库导入机制,统一采用 import 方法进行类文件的加载.import 方法是 ThinkPHP 内建的类库和文件导入方法,提供了方便和灵活的文件导入机制,完全 ...

  3. Spring---Spring Aware

    1.概述 1.1.Spring中的  所有Bean  对Spring容器的存在  是没有意识的(即你可以将容器换成别的容器,这样使用容器与Bean之间的耦合度很低): 但在实际项目中,不可避免的要用到 ...

  4. 简单使用vuex状态管理

    1.在使用vue-cli脚手架创建项目后 npm install vuex 2.创建store文件夹,结构如下: 3.store中 index.js代码如下: 4.入口文件main.js中引入stor ...

  5. 题解 P1033 【自由落体】

    太坑人了 这不是明摆着坑那些没有学完初中物理的同学们 QAQ 首先这个题其实就是转换一下参照系. 由原先小车向小球靠拢换成小车静止,小球向着小车靠拢(原点设置成车右下角那个点). 然后就成了平抛运动. ...

  6. nginx配置-location

    以 =开头表示精确匹配如 A 中只匹配根目录结尾的请求,后面不能带任何字符串. ^~ 开头表示uri以某个常规字符串开头,不是正则匹配 ~ 开头表示区分大小写的正则匹配; ~* 开头表示不区分大小写的 ...

  7. 【ngx-ueditor】百度编辑器按下Shift键不触发contentChange事件

    背景:基于Angular 6,引入ngx-ueditor 发现现象:如果以Shift键+任意键结尾,则ngModel会丢失包含shift键的字符 例如:输入“ABC+AB++++”,则ngModel中 ...

  8. 项目搭建(三):自定义DLL

    说明:程序中有些自定义的控件类型在TestStack.White框架中没有涉及,需要引入自定义的DLL,通过鼠标点击事件处理 使用:将自定义的ClassLibrary2.dll拷贝到项目/bin/de ...

  9. phpStorm debug

    1.重点注意(重要) 如果是wamp,那么请通过wamp打开php.ini文件,不要自己去找php文件夹下的php.ini,这是两个不同的文件 2.开始配置php.ini zend_extension ...

  10. SQL语句:随机取3条不重复的记录

    随机取3条不重复的记录 [Access]select top 3 * from tablename order by rnd(id); [SqlServer]select top 3 * from t ...