此文章用于熟悉 AIO 的基本操作
之前用 NIO 写过,地址:https://blog.csdn.net/yali_aini/article/details/91978722
步骤:
- 1.创建线程池
- 2.创建线程组
- 3.创建服务器通道
- 4.进行绑定 (服务器通道绑定 InetSocketAddress)
- 5.进行阻塞
代码:
import java.net.InetSocketAddress;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class AioServer {
// 线程池
private ExecutorService pool;
// 线程组
private AsynchronousChannelGroup channelGroup;
// 服务器通道
AsynchronousServerSocketChannel serverSocketChannel;
public AioServer(int port){
try {
// 创建一个线程池
this.pool = Executors.newCachedThreadPool();
// 创建线程组
this.channelGroup = AsynchronousChannelGroup.withCachedThreadPool(this.pool , 1);
// 创建服务器通道
this.serverSocketChannel = AsynchronousServerSocketChannel.open(this.channelGroup);
// 进行绑定
this.serverSocketChannel.bind(new InetSocketAddress(port));
// 进行阻塞
this.serverSocketChannel.accept(this , new AioServerCompletionHandler());
System.out.println("server start success...");
// 一直阻塞不让服务停止...
Thread.sleep(Integer.MAX_VALUE);
} catch (Exception e){}
}
public static void main(String[] args) {
new AioServer(8888);
}
}
阻塞的时候需要传递一个 实现了 CompletionHandler<AsynchronousSocketChannel , 当前Server> 的类
AioServerCompletionHandler 类:
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.Base64;
import java.util.Date;
public class AioServerCompletionHandler implements CompletionHandler<AsynchronousSocketChannel, AioServer> {
private static final String ICON = "AAABAAEAQEAAAAEAIAAoQgAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAD/6dn//+HM///48v///+nZ///Lpf//w5n//8OZ///Dmf//w5n//8OZ///Dmf//w5n//+HM///p2fjy///Ssv//tH///6Vl//+IM///iDP//4gz//+IM///iDP//4gz//+WTP//tH///+nZ4cz//5ZM//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+eWf//tH///8OZ///Dmf//w5n//8OZ///Dmf//rXL//55Z//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///rXL///jy0rL//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+eWf//+PL/0rL//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//61y8OX//48///+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///6dn//7R///+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//48Dmf//4czDmf//iDP//4gz//+IM///lkz//9Ky///48v+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//7R///+PP///iDP//4gz//+IM///iDP//4gz//+IM///iDP//7R48v//w5n//4gz//+IM///tHjyiDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+PP//hzP//iDP//4gz//+IM///iDP//4gz//+IM///iDP//7R//8OZ//+IM///jzjy/4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP///Dlw5n//4gz//+IM///iDP//4gz//+IM///iDP//4848v/48v//pWX//4gz//+IM///iDP//4gz///Dmf//iDP//6Vl///w5f//rXL//6Vl//+lZf//pWX//9Ky//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz///hzP///8OZ//+IM///iDP//4gz//+IM///iDP//4gz//+8jP//pWX//4gz//+IM///iDP//4gz//+IM///w5n//4gz//+lZf//jz///4gz//+IM///iDP//4gz///Dmf//iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///4cz///+0f///iDP//4gz//+IM///iDP//4gz//+IM///2r//6dn//4gz//+IM///iDP//4gz//+IM///iDP//8OZ//+IM///pWX//4gz//+IM///iDP//4gz//+IM///w5n//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//+HMw5n//4gz//+IM///iDP//4gz//+IM///iDP//+HM//jy//+IM///iDP//4gz//+IM///iDP//4gz///Dmf//iDP//6Vl//+IM///iDP//4gz//+IM///iDP//8OZ//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz///p2f///9Ky//+IM///iDP//4gz//+IM///iDP//4gz///hzP//iDP//4gz//+IM///iDP//4gz//+IM///w5n//4gz//+lZf//iDP//4gz//+IM///iDP//4gz///Dmf//iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+PP//48v//iDP//4gz//+IM///iDP//4gz//+IM///0rL//48///+IM///iDP//4gz//+IM///iDP//8OZ//+IM///pWX//4gz//+IM///iDP//4gz//+IM///w5n//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///vIz//7R///+IM///iDP//4gz//+IM///iDP//61y///Ssv//iDP//4gz//+IM///iDP//4gz///Dmf//iDP//6Vl//+IM///iDP//4gz//+IM///iDP//8OZ//+IM///iDP//4gz//+IM///iDP//4gz//+IM///jzjy///48v//jz///4gz//+IM///iDP//4gz//+IM///4cz//9q///+lZf//pWX//6Vl//+lZf//w5n//4gz//+lZf//iDP//4gz//+IM///iDP//4gz///Dmf//iDP//4gz//+IM///iDP//4gz//+IM///iDP//9Ky/9q///+IM///iDP//4gz//+IM///iDP//48w5f///8OZ//+IM///pWX//4gz//+IM///iDP//4gz//+IM///w5n//4gz//+IM///iDP//4gz//+IM///iDP//9Ky0rL//4gz//+IM///iDP//4gz//+IM///jz///9qDmf//iDP//6Vl//+IM///iDP//4gz//+IM///iDP//8OZ//+IM///iDP//4gz//+IM///jz///+nZ///Ssv//iDP//4gz//+IM///iDP//4gz//+IM///nln//8OZ///Dmf//w5n//8OZ///Dmf//8OX/w5n//4gz//+PP///pWX//6Vl//+lZf//iDP//4gz//+IM///iDP//4gz//+WTP//pWX//6Vl//+lZf//iDP//4gz//+IM///nln///Dl/+nZ//+PP///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//+HM/8OZ//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///nln///jy+PL//55Z//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz///hzP/Dmf//iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///rXL///jy///48v//tH///4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///4cz/w5n//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///tH+0f///iDP//4gz//+IM///iDP//4gz//+IM///iDP//+HM/8OZ//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///tH///9Ky//+tcv//pWX//6Vl//+lZf//pWX//8ul///48v///9Ky//+IM///iDP//4gz//+IM///iDP//4gz///Lpf//4cz//+HM//+0f///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///nln/+PL//55Z//+IM///iDP//4gz//+IM///iDP//4gz//+IM///jz///+nZy6X//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///nln///jy/55Z//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+WTP//+PL///+0f///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///jzjy/9q///+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//8ul///48v//vIz//4gz//+IM///iDP//4gz//+PP///vIz///jy/55Z//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//+nZ//+0f///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+eWf/48v//nln//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+eWf//+PLw5f//jz///4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//8OZpWX//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP/vIz//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//6Vl/8ul//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//6Vl/6Vl//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz///48v//8OX//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///2r//tH///4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//55Z///48v+eWf//iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///4cz//7yM//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//61y//+0f///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//55Z///48v//nln//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//+HM//+eWf//iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+WTP///9q///+WTP//iDP//4gz//+IM///iDP//4gz//+IM///iDP//7yM///48v///6Vl//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz///w5f//iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//9qDmf//pWX//6Vl//+0f///y6X///jy//+lZf//iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gzvIz//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///pWX///+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM9q///+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//9Kylkz//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP/lkz//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//55Z/61y//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//55Z/+HM//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//55Z///48v/Ssv//iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz///Dmf/p2f//6dn/4cz//7R///+lZf//pWX//7RhzP//4cz//5ZM//+IM///iDP//4gz//+IM///iDP//7R48v//+PL//48///+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+PP///+PL//8OZ//+PP///iDP//4gz//+PP///w5n48v//pWX//4gz//+IM///iDP//4gz//+IM///iDP//61y///48v//6dn//+HM///hzP//4cz///jy///Dmf//iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///0rL//7R///+IM///iDP//4gz//+IM///iDP//4gz//+0f///rXL//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///nln///jy/55Z//+IM///iDP//4gz//+IM///iDP//4gz//+IM///tH///8OZ//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//8OZ4cz//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+8jP/48v//rXL//4gz//+IM///iDP//4gz//+WTP//2rDl//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///8OX//7R///+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP///Dl///w5f//0rL//8OZ///hzP/Lpf//iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//8ul//+lZf//iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+0f///nln//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+eWf//jz///4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz///hzP+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+WTP//iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///y6X/iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///pWX//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//8ul/4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//8ul//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz///hzP+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz///48v//jz///4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+PP///pWX//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+lZf///8OZ//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///tH///8ul//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///y6X/nln//4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///jzjy///48v//jz///4gz//+IM///iDP//4gz//+IM///iDP//4gz//+IM///jzjy//jy//+eWf//iDP//4gz//+IM///iDP//4gz//+IM///jz///+nZ/8ul//+IM///iDP//4gz//+IM///iDP//4gz//+IM///iDP//9Ky+PL//6Vl//+IM///iDP//4gz//+IM///lkz//+nZtH///4gz//+IM///iDP//4gz//+IM///iDP//7R/2r///7R///+tcv//0rL///jy///av///nln//4gz//+IM///nln//9q/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
// 两个常量
private static final String CRLF = "\r\n";
private static final String BLANK = " ";
@Override
public void completed(AsynchronousSocketChannel result, AioServer attachment) {
// 当有客户端接入的时候,直接阻塞
attachment.serverSocketChannel.accept(attachment, this);
// 读写数据
readAndWrite(result);
}
public void readAndWrite(final AsynchronousSocketChannel channel) {
ByteBuffer buffer = ByteBuffer.allocate(1024);
channel.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer result, ByteBuffer attachment) {
// 读取之后进行复位
attachment.flip();
System.out.println("data length is " + result);
String in = new String(attachment.array()).trim();
System.out.println(in);
write(channel , in , "收到你的消息了,我知道了...");
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
exc.printStackTrace();
System.out.println("读取失败!" + channel);
}
});
}
public void write(final AsynchronousSocketChannel channel ,String request , String res){
writeData(channel , request , res);
}
public void writeData(AsynchronousSocketChannel socketChannel , String in , String res){
try{
StringBuffer sb = new StringBuffer();
// http 协议版本,状态码,描述
sb.append("HTTP/1.1").append(BLANK).append(200).append(BLANK).append("love").append(CRLF);
// 响应头
sb.append("Server:Pkusoft Server/12.19.06.14").append(CRLF).append("Date:").append(new Date()).append(CRLF);
String html = "";
if( in.contains("favicon.ico") ){
byte [] data = Base64.getDecoder().decode(ICON);
sb.append("Content-type:image/x-icon").append(CRLF);
sb.append("Connection:keep-alive").append(CRLF);
sb.append("Content-Length:").append( data.length ).append(CRLF).append(CRLF);
socketChannel.write(ByteBuffer.wrap(sb.toString().getBytes()));
socketChannel.write(ByteBuffer.wrap(data));
}else{
sb.append("Content-type:text/html").append(CRLF);
html = "<meta charset='utf-8' /><h1>nio 牛批</h1>";
html += "<pre>"+ res +"</pre>";
sb.append("Connection:keep-alive").append(CRLF);
// 正文长度:内容
sb.append("Content-Length:").append( html.getBytes().length ).append(CRLF).append(CRLF);
sb.append(html);
socketChannel.write(ByteBuffer.wrap(sb.toString().getBytes()));
}
}catch (Exception e){
e.printStackTrace();
}
}
@Override
public void failed(Throwable exc, AioServer attachment) {
exc.printStackTrace();
System.out.println(attachment + ":failed...");
}
}
Client 代码:
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.charset.Charset;
import java.util.concurrent.Future;
public class AioClient {
public static void main(String[] args) throws Exception {
AsynchronousSocketChannel socketChannel = AsynchronousSocketChannel.open();
socketChannel.connect(new InetSocketAddress("127.0.0.1",8888));
ByteBuffer buffer = ByteBuffer.allocate(1024);
socketChannel.write(Charset.forName("UTF-8").encode("你好 nio"));
Future<Integer> future = socketChannel.read(buffer);
System.out.println( future.get() );
buffer.flip();
System.out.println( new String(buffer.array()).trim() );
}
}
此处有个问题,就是 read 的时候,只能读取给定的 ByteBuffer 的,不知道怎么循环读取,知道读取完毕,有知道的,忘告知。