JavaIO网络模型——异步IO(AIO)

简介

  • 概念:异步IO模型(Asynchronous IO)简称AIO,其基本流程时:用户线程通过系统调用,向内核注册某个IO操作。内核在整个IO操作(包括数据准备、数据复制)完成后,通知用户程序,执行后续的业务操作。在异步IO模型中,整个内核的数据处理过程中,包括内核将数据从网络物理设备(网卡)读取到内核缓存区、将内核缓冲区的数据复制到用户缓冲区,用户程序都不需要阻塞。
  • 理解:女友不想逛街,回家好好休息一下。于是我们叫外卖,打个电话点餐,然后我和女友可以在家好好休息一下,饭好了送货员送到家里来。这就是典型的异步,

过程

在这里插入图片描述

特点

  • 优点:在内核等待数据和复制数据的两个阶段,用户线程都不是阻塞的。
  • 缺点:需要操作系统底层内核提供支持,CPU开销太大。

应用

  • 连接数目比较多以及连接时间长的系统架构

简单实现

  1. 服务器
public class MyAIOServer {
    public static void main(String[] args) {
        AsynchronousServerSocketChannel serverSocketChannel = null;
        try {
            //创建AsynchronousServerSocketChannel
            serverSocketChannel = AsynchronousServerSocketChannel.open();
            //绑定端口
            serverSocketChannel.bind(new InetSocketAddress(9999));
            //监听
            serverSocketChannel.accept(serverSocketChannel,new ServerHandler());
            System.out.println("服务器已启动...");
            //创建CountDownLatch
            CountDownLatch countDownLatch = new CountDownLatch(1);
            countDownLatch.await();
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }finally {
            try {
                if (serverSocketChannel != null){
                    serverSocketChannel.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
  1. ServerHandler
public class ServerHandler implements CompletionHandler<AsynchronousSocketChannel, AsynchronousServerSocketChannel> {

    @Override
    public void completed(AsynchronousSocketChannel result, AsynchronousServerSocketChannel attachment) {
        //处理下一次用户请求
        attachment.accept(attachment, new ServerHandler());
        //读数据
        doRead(result);
    }

    @Override
    public void failed(Throwable exc, AsynchronousServerSocketChannel attachment) {
            exc.printStackTrace();
    }

    private void doRead(AsynchronousSocketChannel channel) {
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        channel.read(byteBuffer, byteBuffer, new CompletionHandler<Integer, ByteBuffer>() {
            @Override
            public void completed(Integer result, ByteBuffer attachment) {
                byteBuffer.flip();
                System.out.println("客户端发送的数据为: "+new String(byteBuffer.array()));
                //写操作
                doWrite(channel);
            }

            @Override
            public void failed(Throwable exc, ByteBuffer attachment) {
                exc.printStackTrace();
            }
        });
    }

    private void doWrite(AsynchronousSocketChannel channel){
        //进行写操作
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入响应数据:");
        String info = scanner.nextLine();
        byteBuffer.put(info.getBytes(StandardCharsets.UTF_8));
        byteBuffer.flip();
        channel.write(byteBuffer, byteBuffer, new CompletionHandler<Integer, ByteBuffer>() {
            @Override
            public void completed(Integer result, ByteBuffer attachment) {
                doRead(channel);
            }

            @Override
            public void failed(Throwable exc, ByteBuffer attachment) {
                exc.printStackTrace();
            }
        });
    }
}
  1. 客户端
package com.xatu.netWorkPractice.aio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
import java.util.concurrent.ExecutionException;

public class MyAIOClient {
    private AsynchronousSocketChannel channel;

    public MyAIOClient(String host, int port){
        init(host, port);
    }

    public void init(String host, int port){
        try {
            //开启通道
            channel = AsynchronousSocketChannel.open();
            //发起连接请求
            channel.connect(new InetSocketAddress(host, port));
            System.out.println("客户端已启动...");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void write(String line){
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        buffer.put(line.getBytes(StandardCharsets.UTF_8));
        buffer.flip();
        channel.write(buffer);
    }

    public void read(){
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        try {
            channel.read(buffer).get();
            buffer.flip();
            System.out.println("来自服务器端数据:"+new String(buffer.array()));
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }

    public void shutDown(){
        try {
            if (channel != null){
                channel.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        MyAIOClient client = new MyAIOClient("127.0.0.1", 9999);
        try {
            while (true) {
                System.out.println("请输入请求数据:");
                Scanner scanner = new Scanner(System.in);
                String info = scanner.nextLine();
                client.write(info);
                client.read();
                if ("".equals(info) || "exit".equals(info)) {
                    break;
                }
            }
        }finally {
            client.shutDown();
        }
    }
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值