解释:AIO → Asynchronous input output(异步非阻塞式的输入和输出)
NIO(2.0)版本真正的异步非阻塞机制
一、 服务端
AioServer :AIO的服务端
ServerCompletionHandler: 用来处理某个客户端请求
/**
* aio服务器端;非阻塞异步机制,JDK1.7后才有
* @author zhb
*/
public class AioServer {
// 线程池
private ExecutorService executorService;
// 异步线程组
private AsynchronousChannelGroup threadGroup;
// 异步服务通道
public AsynchronousServerSocketChannel assc;
// 开启aio服务端
public AioServer(int port){
try {
// 创建一个缓存线程池
executorService = Executors.newCachedThreadPool();
// 创建异步线程组
threadGroup = AsynchronousChannelGroup.withCachedThreadPool(executorService, 1);
// 创建服务器通道
assc = AsynchronousServerSocketChannel.open(threadGroup);
// 服务通道和端口绑定
assc.bind(new InetSocketAddress(port));
System.err.println("Aio服务通道开启————————port" + port);
//进行阻塞 ,不是真正的阻塞
assc.accept(this, new ServerCompletionHandler());
Thread.sleep(Integer.MAX_VALUE);
} catch (IOException e) {
e.printStackTrace();
}catch (InterruptedException e) {
e.printStackTrace();
}
}
// 主函数
public static void main(String[] args) {
new AioServer(Constant.serverSocketPort);
}
}
/**
* 处理具体的某个客户的请求
* @author zhb
*/
public class ServerCompletionHandler implements CompletionHandler<AsynchronousSocketChannel, AioServer> {
public void completed(AsynchronousSocketChannel asc, AioServer aioServer) {
// 当下客户处理后,再开启一个阻塞,继续服务下一个客户端请求
aioServer.assc.accept(aioServer, this);
// 读取数据
doRead(asc);
}
/**
* 读取客户端的请求信息
* @param asc
*/
private void doRead(final AsynchronousSocketChannel asc) {
ByteBuffer buffer = ByteBuffer.allocate(1024);
// 异步读取数据
asc.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {
// 重写没有实现的方法
public void completed(Integer reqByteLength, ByteBuffer byteBuffer) {
// 读取数据后。整理数据,重新复位
byteBuffer.flip();
// 获取读取的字节数
System.err.println("server---获取客户端的请求的字节长度:" + reqByteLength);
try {
// 获取请求端数据
String reqStr = new String(byteBuffer.array(), Constant.charset).trim();
System.err.println("server---获取客户端的请求的请求数据为:" + reqStr);
// 处理请求信息
handlerReq(asc, reqStr);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
public void failed(Throwable exc, ByteBuffer attachment) {
exc.printStackTrace();
}
});
}
/**
* 处理客户请求信息
* @param asc
* @param reqStr 客户请求信息
* @throws UnsupportedEncodingException
* @throws ExecutionException
* @throws InterruptedException
*/
private void handlerReq(AsynchronousSocketChannel asc, String reqStr) throws UnsupportedEncodingException, InterruptedException, ExecutionException {
// 处理请求,得到相应的返回信息
String respStr = "服务器返回信息是:"+ reqStr;
byte[] respStrByte = respStr.getBytes(Constant.charset);
ByteBuffer respStrBuffer = ByteBuffer.allocate(1024);
respStrBuffer.put(respStrByte);
respStrBuffer.flip();
// 异步返回响应信息
asc.write(respStrBuffer).get();
System.err.println("服务端响应成功:" +respStr);
}
public void failed(Throwable exc, AioServer attachment) {
exc.printStackTrace();
}
}
一、 客户端
/**
* aio 客户端请求
* @author zhb
*/
public class ClientReq implements Runnable{
// 异步socketchannel
private AsynchronousSocketChannel asc;
public ClientReq() throws IOException{
this.asc = AsynchronousSocketChannel.open();
}
public void connect(){
this.asc.connect(new InetSocketAddress("localHost", Constant.serverSocketPort));
}
// 客户端写数据
public void write(String reqStr) throws UnsupportedEncodingException, InterruptedException, ExecutionException{
this.asc.write(ByteBuffer.wrap(reqStr.getBytes(Constant.charset))).get();
read();
}
// 客户端读数据
private void read() throws InterruptedException, ExecutionException, UnsupportedEncodingException {
ByteBuffer respBuffer = ByteBuffer.allocate(1024);
this.asc.read(respBuffer).get();
respBuffer.flip();
byte[] respByte = new byte[respBuffer.remaining()];
respBuffer.get(respByte);
String respStr = new String(respByte, Constant.charset);
System.err.println("client收到服务端的返回信息===" + respStr);
}
public void run() {
while(true){
}
}
// 主线程
public static void main(String[] args) throws IOException, InterruptedException, ExecutionException {
ClientReq client = new ClientReq();
client.connect();
new Thread(client).start();
Thread.sleep(1000);
client.write("client");
}
}