java核心学习(三十三) 网络编程---AIO实现异步Socket通信

  AIO需要操作系统的支持,在linux内核2.6版本中加入了对真正异步IO的支持,java从jdk1.7开始支持AIO

核心类有AsynchronousSocketChannel 、AsynchronousServerSocketChannel、AsynchronousChannelGroup

  前两个个类是javaAIO为TCP通信提供的异步Channel。看名字就知道应该是干什么的了。

  创建AsynchronousServerSocketChannel的代码如下:    

AsynchronousServerSocketChannel serverChannel = AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(PORT));

  其中open()有一个重载方法,可以使用指定的AsynchronousChannelGroup来创建AsynchronousServerSocketChannel。

  AsynchronousChannelGroup是异步Channel的分组管理器,它可以实现资源共享。创建AsynchronousChannelGroup时,需要传入一个ExecutorService,也就是绑定一个线程池,该线程池负责两个任务:处理IO事件和触发CompletionHandler回调接口。代码如下:

  

AsynchronousServerSocketChannel serverSocketChannel = null;
        try {
            ExecutorService executorService = Executors.newFixedThreadPool(80);
            AsynchronousChannelGroup channelGroup = AsynchronousChannelGroup.withThreadPool(executorService);
            serverSocketChannel = AsynchronousServerSocketChannel.open(channelGroup).bind(new InetSocketAddress(9000));
        }catch (IOException ioe){
            ioe.printStackTrace();
        }

    AsynchronousServerSocketChannel创建成功后,类似于ServerSocket,也是调用accept()方法来接受来自客户端的连接,由于异步IO实际的IO操作是交给操作系统来做的,用户进程只负责通知操作系统进行IO和接受操作系统IO完成的通知。所以异步的ServerChannel调用accept()方法后,当前线程不会阻塞,程序也不知道accept()方法什么时候能够接收到客户端请求并且操作系统完成网络IO,为解决这个问题,AIO为accept方法提供两个版本:

    Future<AsynchronousSocketChannel> accept() :开始接收客户端请求,如果当前线程需要进行网络IO(即获得AsynchronousSocketChannel),则应该调用该方法返回的Future对象的get()方法,但是get方法会阻塞该线程,所以这种方式是阻塞式的异步IO。

    <A> void accept(A attachment ,CompletionHandler<AsynchronousSocketChannel,? super A> handler):开始接受来自客户端请求,连接成功或失败都会触发CompletionHandler对象的相应方法。其中AsynchronousSocketChannel就代表该CompletionHandler处理器在处理连接成功时的result是AsynchronousSocketChannel的实例。

    而CompletionHandler接口中定义了两个方法,

      completed(V result , A attachment):当IO完成时触发该方法,该方法的第一个参数代表IO操作返回的对象,第二个参数代表发起IO操作时传入的附加参数。

      faild(Throwable exc, A attachment):当IO失败时触发该方法,第一个参数代表IO操作失败引发的异常或错误。

    使用第一种accept方法需要如下代码

    

while (true){
            Future<AsynchronousSocketChannel> future = serverSocketChannel.accept();
            AsynchronousSocketChannel socketChannel = null;
            try {
                socketChannel = future.get();
                socketChannel.write(ByteBuffer.wrap("ssss".getBytes("UTF-8")));
            }catch (Exception e){
                e.printStackTrace();
            }


        }

    通常使用第二种accept,实现自己的CompletionHandler实现类。

 

    而AsynchronousSocketChannel的的用法与Socket类似,由三个方法,但是不同的是每个方法又分为Future版本与CompletionHandler版本。

      connect():用于连接到指定端口,指定IP地址的服务器

      read()、write():完成读写。

    注意!使用异步Channel时,accept()、connect()、read()、write()等方法都不会阻塞,也就是说如果使用返回Future的这些方法,程序并不能直到什么时候成功IO,必须要使用get方法,等get方法的阻塞结束后才能确保IO完成,继续执行下面的操作。

转载于:https://www.cnblogs.com/Theshy/p/7696313.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值