AIO 全程 Asynchronous I/O,它是异步的,客户端发起请求之后不需要等待服务端响应可以做其他的事情,然后服务端业务逻辑处理完之后会将处理结果通知客户端。客户端这个时候会到指定的缓冲区获取数据。
与 NIO 不同的地方在于,Channel 对应的接口是异步的,主要涉及到的类:AsynchronousServerSocketChannel(服务器接收请求通道)、AsynchronousSocketChannel(Socket 通讯通道)、CompletionHandler(异步处理类)。
package net.haicoder.server;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class AioServer {
private final int port;
public static void main(String[] args) {
int port = 9999;
new AioServer(port);
}
public AioServer(int port) {
this.port = port;
listen();
while (true) {
try {
Thread.sleep(1000000);
} catch (InterruptedException e) {
}
}
}
private void listen() {
try {
ExecutorService executorService = Executors.newCachedThreadPool();
AsynchronousChannelGroup threadGroup = AsynchronousChannelGroup.withCachedThreadPool(executorService, 1);
final AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open(threadGroup);
serverSocketChannel.bind(new InetSocketAddress(port));
System.out.println("服务已经启动,监听端口:" + port);
serverSocketChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Object>() {
final ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
@Override
public void completed(AsynchronousSocketChannel result, Object attachment) {
System.out.println("I/O 操作成功,开始获取数据");
try {
byteBuffer.clear();
result.read(byteBuffer).get();
byteBuffer.flip();
System.out.println("服务端接收到数据:" + new String(byteBuffer.array()).trim());
result.write(byteBuffer);
byteBuffer.flip();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
result.close();
serverSocketChannel.accept(null, this);
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("操作完成");
}
@Override
public void failed(Throwable exc, Object attachment) {
System.out.println("I/O 操作失败:" + exc);
}
});
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
package net.haicoder.client;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
public class AioClient {
private AsynchronousSocketChannel clientChannel;
private static final String host = "127.0.0.1";
private static final Integer port = 9999;
public AioClient() throws Exception {
clientChannel = AsynchronousSocketChannel.open();
}
public void connect(String host, int port) {
try {
clientChannel.connect(new InetSocketAddress(host, port), null, new CompletionHandler<Void, Void>() {
@Override
public void completed(Void result, Void attachment) {
try {
clientChannel.write(ByteBuffer.wrap("你好嗨客网,客户端链接成功了".getBytes())).get();
System.out.println("数据已经发送成功!");
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void failed(Throwable exc, Void attachment) {
}
});
} catch (Exception e) {
e.printStackTrace();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 定义一个ByteBuffer准备读取数据
final ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
clientChannel.read(byteBuffer, null, new CompletionHandler<Integer, Object>() {
@Override
public void completed(Integer result, Object attachment) {
System.out.println("I/O操作完成" + result);
System.out.println("获取返回结果:" + new String(byteBuffer.array()).trim());
}
@Override
public void failed(Throwable exc, Object attachment) {
exc.printStackTrace();
}
});
}
public static void main(String[] args) throws Exception {
AioClient aioClient = new AioClient();
aioClient.connect(host, port);
}
}
运行结果如下:
在项目测试的时候,和前面的 IO 一样,也是需要先启动服务端,然后再启动客户端。
AIO 是完全异步非阻塞的模型,当客户端向服务端发起请求之后,客户端不需要等待也不需要轮询结果,服务端执行完之后会通知客户端让客户端进行处理。
主要涉及到的类:AsynchronousServerSocketChannel(服务器接收请求通道)、AsynchronousSocketChannel(Socket 通讯通道)、CompletionHandler(异步处理类)。