AIO - 概述

简介: 介绍AIO使用,以及AIO使用的执行过程


本博客是《Netty威指南》的读书,如有错误环境指正、探谢谢!此码见附件。

此博客涉及的代码地址https://gitee.com/wuzhengfei/great-truth;参考com.wzf.greattruth.aio包中的代

IO模型参考:https://yq.aliyun.com/articles/277102


JDK1.7升级了NIO类库,升级后的NIO类库被称为NIO2.0,此版本正式提供了异步IO操作,即AIO。

 

1. AIO服务端序列

adcc8021b13070ba6bf4b76f5c30d3821ed03f05

 

2. AIO服务端序列分析

1)打开AsynchronousServerSocketChannel

asynServerSocketChannel = AsynchronousServerSocketChannel.open();

 

2) 绑定监听地址InetSocketAddress

asynServerSocketChannel.bind(new InetSocketAddress(port));

 

3) 创建线程并启动

AsyncServerHandler timeServer = new AsyncServerHandler(port);

new Thread(timeServer, "AIOServerHandler").start();

 

4)注册接收数据的Handler

asynServerSocketChannel.accept(this, new ServerAcceptCompletionHandler());

 

5)接收数据,实现ServerAcceptCompletionHandler的completed、failed方法


public void completed(AsynchronousSocketChannel channel, AsyncServerHandler attachment) {

    /**

    * 为什么需要再次调用accept方法?

    * 因为如果有新的客户端连接接入,系统将回调我们传入的CompletionHandler示例的complete方法,表示新的客户端接入成功

    * 因为一个AsynchronousServerSocketChannel可以接收成千上万个客户端,所以需要继续调用他的accept方法,

    * 接收其他客户端连接,最终形成一个循环。每当接收一个客户连接成功后,再异步接收新的客户端连接

    * 

    */

        attachment.asynServerSocketChannel.accept(attachment, this);

    ByteBuffer buffer = ByteBuffer.allocate(1024);

    /**

    * ByteBuffer:接收缓冲区,用于从异步的Channel中读取数据包

    * Attachment:异步Channel携带的附件,通知回调的时候作为入参使用

    * CompletionHandler:接收通知回调的业务Handler

    */

    channel.read(buffer, buffer, new ServerReadCompletionHandler(channel));

    }

 

public void failed(Throwable exc, AsyncServerHandler attachment) {

    exc.printStackTrace();

    attachment.latch.countDown();

}


 

6)读取数据,实现ServerReadCompletionHandler的Complete、faild方法

public void completed(Integer result, ByteBuffer attachment) {

    // handler with data

}

public void failed(Throwable exc, ByteBuffer attachment) {

    this.channel.close();

}


 

7)decode数据 

attachment.flip();

byte[] body = new byte[attachment.remaining()];

attachment.get(body);

String req = new String(body, "UTF-8");

 

8)异步写数据到Channel

byte[] bytes = (response).getBytes();

ByteBuffer writeBuffer = ByteBuffer.allocate(bytes.length);

writeBuffer.put(bytes);

writeBuffer.flip();

channel.write(writeBuffer, writeBuffer, new CompletionHandler<Integer, ByteBuffer>() {

    @Override

    public void completed(Integer result, ByteBuffer buffer) {

        // 如果没有发送完成,继续发送

        if (buffer.hasRemaining())

             channel.write(buffer, buffer, this);

    }

 

    @Override

    public void failed(Throwable exc, ByteBuffer attachment) {

        try {

             channel.close();

        } catch (IOException e) {

             // ingnore on close

        }

    }

});


3.AIO客户端序列

dbd127f098f47e5827f1d4b16833ace278700fe9

 

4. AIO客户端序列分析

1)打开AsynchronousSocketChannel

asynSocketChannel = AsynchronousSocketChannel.open();

 

2)异步连接服务器

asynSocketChannel.connect(new InetSocketAddress(host, port), this, this);

3)创建线程并启动 


AsyncClientHandler asyncClientHandler = new AsyncClientHandler("127.0.0.1", port);

new Thread(asyncClientHandler, "AIOClientHandler").start();

 

4)注册连接Server成功的Handler

ClientConnectCompletionHandler connectCompletionHandler = new ClientConnectCompletionHandler(asynSocketChannel, latch) ;

asynSocketChannel.connect(new InetSocketAddress(host, port), connectCompletionHandler, connectCompletionHandler);

 

5)连接成功后,注册向Server写数据的Handler,实现Completed、Failed方法

public void completed(Void result, AsyncClientHandler attachment) {

    byte[] req = "timestemp".getBytes();

    ByteBuffer writeBuffer = ByteBuffer.allocate(req.length);

    writeBuffer.put(req);

    writeBuffer.flip();

 

    ClientWriteCompletionHandler writeCompletionHandler = new ClientWriteCompletionHandler(

             attachment.asynSocketChannel, attachment.latch);

    attachment.asynSocketChannel.write(writeBuffer, writeBuffer, writeCompletionHandler);

}

 

@Override

public void failed(Throwable exc, AsyncClientHandler attachment) {

    exc.printStackTrace();

    try {

        attachment.asynSocketChannel.close();

        attachment.latch.countDown();

    } catch (IOException e) {

        e.printStackTrace();

    }

}


 

 

6)向Server发送数据,实现CompletionHandler的Completed、faild方法


public void completed(Integer result, ByteBuffer buffer) {

    if (buffer.hasRemaining()) {

        asynSocketChannel.write(buffer, buffer, this);

    }

}

 

public void failed(Throwable exc, ByteBuffer attachment) {

    try {

        asynSocketChannel.close();

        latch.countDown();

    } catch (IOException e) {

        // ingnore on close

    }

}


 

7)注册读数据的Handler,实现completed、failed方法

asynSocketChannel.read(readBuffer, readBuffer, new CompletionHandler<Integer, ByteBuffer>() {

    @Override

    public void completed(Integer result, ByteBuffer buffer) {

        buffer.flip();

        byte[] bytes = new byte[buffer.remaining()];

        buffer.get(bytes);

        String body;

        try {

             body = new String(bytes, "UTF-8");

             System.out.println("Now is : " + body);

             latch.countDown();

        } catch (UnsupportedEncodingException e) {

             e.printStackTrace();

        }

    }

 

    @Override

    public void failed(Throwable exc, ByteBuffer attachment) {

        try {

             asynSocketChannel.close();

             latch.countDown();

        } catch (IOException e) {

             // ingnore on close

        }

    }

});

 

8)读取并decode数据


buffer.flip();

byte[] bytes = new byte[buffer.remaining()];

buffer.get(bytes);

String body = new String(bytes, "UTF-8");


 

 

相关文章
|
20天前
|
网络协议 Dubbo Java
一文搞懂NIO、AIO、BIO的核心区别(建议收藏)
本文详细解析了NIO、AIO、BIO的核心区别,NIO的三个核心概念,以及NIO在Java框架中的应用等。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
一文搞懂NIO、AIO、BIO的核心区别(建议收藏)
|
5月前
|
安全 Java Linux
(七)Java网络编程-IO模型篇之从BIO、NIO、AIO到内核select、epoll剖析!
IO(Input/Output)方面的基本知识,相信大家都不陌生,毕竟这也是在学习编程基础时就已经接触过的内容,但最初的IO教学大多数是停留在最基本的BIO,而并未对于NIO、AIO、多路复用等的高级内容进行详细讲述,但这些却是大部分高性能技术的底层核心,因此本文则准备围绕着IO知识进行展开。
173 1
|
5月前
|
存储 Java Unix
(八)Java网络编程之IO模型篇-内核Select、Poll、Epoll多路复用函数源码深度历险!
select/poll、epoll这些词汇相信诸位都不陌生,因为在Redis/Nginx/Netty等一些高性能技术栈的底层原理中,大家应该都见过它们的身影,接下来重点讲解这块内容。
|
缓存 网络协议 Unix
Linux IO模型:阻塞/非阻塞/IO复用 同步/异步 Select/Epoll/AIO
IO概念 Linux的内核将所有外部设备都可以看做一个文件来操作。那么我们对与外部设备的操作都可以看做对文件进行操作。我们对一个文件的读写,都通过调用内核提供的系统调用;内核给我们返回一个file descriptor(fd,文件描述符)。
2844 0
|
6月前
|
Linux C++
c++高级篇(三) ——Linux下IO多路复用之poll模型
c++高级篇(三) ——Linux下IO多路复用之poll模型
|
6月前
|
缓存 监控 网络协议
c++高级篇(二) ——Linux下IO多路复用之select模型
c++高级篇(二) ——Linux下IO多路复用之select模型
|
6月前
|
Java 视频直播 数据库连接
Java I/O 模型详解:BIO、NIO 与 AIO 的特性与应用
Java I/O 模型详解:BIO、NIO 与 AIO 的特性与应用
69 2
|
消息中间件 存储 网络协议
Linux五种I/O模式 NIO BIO AIO IO多路复用 信号驱动 I/O
Linux五种I/O模式 NIO BIO AIO IO多路复用 信号驱动 I/O
250 0
|
JSON 网络协议 关系型数据库
计网 - 网络 I/O 模型:BIO、NIO 和 AIO 有什么区别?
计网 - 网络 I/O 模型:BIO、NIO 和 AIO 有什么区别?
116 0