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

void accept(A attachment ,CompletionHandler 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 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完成,继续执行下面的操作。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值