目录
1.AIO介绍
AIO模型是Java中提供的异步非阻塞网络IO模型,如下图所示,用户进程进行系统调用后,可以处理其他逻辑,无论内核数据是否准备好,都会直接返回给用户进程,进程不会阻塞。数据准备好,内核直接复制数据到用户空间,内核向进程发送通知。
内核向用户空间拷贝数据的工作是由内核完成的而不是应用进程。
AIO需要一个连接注册读写事件和回调方法,当进行读写操作时,直接调用API的read和write方法。对应操作系统来说, 当有流数据可读时, 操作系统会将流传入到read方法的缓冲区, 然后回调相关的 CompletionHandler;对于写操作而言, 操作系统会将程序中Buffer里面数据写入到从用户空间写入到系统空间 再写入到网卡中, 写入完毕, 同样会回调相关的回调函数。
读写方法完成后会调用回调函数。
2.AIO相关类
2.1 服务器端Socket通道类:AsynchronousServerSocketChannel
主要方法:accept()
//accept方法用于接收连接请求,第一个参数是附件,第二个参数是收到请求后的接收处理器(回调)。
//对应的处理器泛型,第一个参数是处理结果(这里为AsynchronousSocketChannel,即接收到的请求channel),第二个参数是附件。
public abstract <A> void accept(A attachment,
CompletionHandler<AsynchronousSocketChannel,? super A> handler);
2.2 客户端Socket通道类:AsynchronousSocketChannel
主要方法connect()、read()\write()
//connect()
//第一个参数为连接的目标地址,第二参数为附件,第三个参数为连接处理器。
//对应的处理器泛型,第一个参数为空(即Void),第二个参数为附件;
public abstract <A> void connect(SocketAddress remote,
A attachment,
CompletionHandler<Void,? super A> handler);
//read()
//第一个参数是数据读取到的目标缓存,第二个参数是附件,第三个参数是读取结束后的处理器。
//对应的处理器泛型,第一个参数是读取的字节数,第二个是附件类型;
public final <A> void read(ByteBuffer dst,
A attachment,
CompletionHandler<Integer,? super A> handler)
{
read(dst, 0L, TimeUnit.MILLISECONDS, attachment, handler);
}
//write()
//第一个参数是数据写入的缓存,第二个参数是附件,第三个参数是写结束后的处理器
//对应的处理器泛型,第一个参数是写入的字节数,第二个是附件类型;
public final <A> void write(ByteBuffer src,
A attachment,
CompletionHandler<Integer,? super A> handler)
{
write(src, 0L, TimeUnit.MILLISECONDS, attachment, handler);
}
2.3 CompletionHandler接口
public interface CompletionHandler<V,A> {
void completed(V result, A attachment);
void failed(Throwable exc, A attachment);
}
3.代码实现
3.1服务器端
//server
public class server {
private int port = 5676;
private AsynchronousServerSocketChannel serverChannel;
private CountDownLatch latch;
public server() {
try {
//创建serverSocketChannel实例并且绑定监听地址和端口号
serverChannel = AsynchronousServerSocketChannel.open();
serverChannel.bind(new InetSocketAddress(port));
} catch (IOException e) {
e.printStackTrace();
}
}
public CountDownLatch getLatch() {
return latch;