所谓AIO,即是异步IO,它的IO操作交由操作系统完成。设置监听器(类似于一个信号处理函数),当系统IO操作完成时,会被监听器监听到,并执行相应的后续操作,然后返回。
监听器一般使用CompletionHandler。
服务器端代码:
package com.nanhao.AIOTest;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.*;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Server {
static final int PORT = 3000;
final static String UTF_8 = "utf-8";
static List<AsynchronousSocketChannel>channelList = new ArrayList<>();
public void startListen()throws IOException,Exception{
//创建一个线程池
ExecutorService executorService = Executors.newFixedThreadPool(20);
//以指定的线程池来创建一个AsynchronousChannelGroup
AsynchronousChannelGroup channelGroup = AsynchronousChannelGroup.withThreadPool(executorService);
//通过channelGroup来创建一个AsynchronousServerSocketChannel
AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open(channelGroup)
//指定监听本机的端口
.bind(new InetSocketAddress("127.0.0.1",PORT));
//使用监听器来接收来自客户端的链接请求
serverSocketChannel.accept(null,new AcceptHandler(serverSocketChannel));
}
public static void main(String[]args)throws Exception{
Server server = new Server();
server.startListen();
}
class AcceptHandler implements CompletionHandler<AsynchronousSocketChannel,Object>{
private AsynchronousServerSocketChannel serverSocketChannel;
public AcceptHandler(AsynchronousServerSocketChannel serverSocketChannel) {
this.serverSocketChannel = serverSocketChannel;
}
//定义一个ByteBuffer准备读取数据
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
@Override
public void completed(final AsynchronousSocketChannel result, Object attachment) {
Server.channelList.add(result);
serverSocketChannel.accept(null,this);
result.read(byteBuffer, null, new CompletionHandler<Integer, Object>() {
@Override
public void completed(Integer result, Object attachment) {
byteBuffer.flip();
//将buffer中的字节转换为字符
String context = StandardCharsets.UTF_8.decode(byteBuffer).toString();
//由于是聊天室,所以将所有的channel里面写入这个消息
for(AsynchronousSocketChannel ass:Server.channelList){
try{
ass.write(ByteBuffer.wrap(context.getBytes(Server.UTF_8))).get();
}catch(Exception e){
e.printStackTrace();
}
}
byteBuffer.clear();
result.read(byteBuffer,null,this);
}
@Override
public void failed(Throwable exc, Object attachment) {
System.out.println("读取数据失败: "+exc);
Server.channelList.remove(result);
}
});
}
@Override
public void failed(Throwable exc, Object attachment) {
System.out.println("连接失败 :"+exc);
}
}
}