本文共 2254 字,大约阅读时间需要 7 分钟。
AIO,A是Asynchronous 异步的。只要是异步,一定是不会阻塞住主线程,也一定是要有回调函数。
具体server端的示例代码如下:
public class Server { public static void main(String[] args) throws Exception { AsynchronousServerSocketChannel serverChannel = AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(8888)); serverChannel.accept(null, new CompletionHandler() { @Override public void completed(AsynchronousSocketChannel client, Object attachment) { serverChannel.accept(null, this); try { System.out.println(client.getRemoteAddress()); ByteBuffer buffer = ByteBuffer.allocate(1024); client.read(buffer, buffer, new CompletionHandler () { @Override public void completed(Integer result, ByteBuffer attachment) { attachment.flip(); System.out.println(new String(attachment.array(),0,result)); client.write(ByteBuffer.wrap("HelloClient".getBytes())); } @Override public void failed(Throwable exc, ByteBuffer attachment) { exc.printStackTrace(); } }); } catch (IOException e) { e.printStackTrace(); } } @Override public void failed(Throwable exc, Object attachment) { exc.printStackTrace(); } }); System.out.println("服务已启动"); while(true){ Thread.sleep(1000); } }}
BIO的server端创建的是ServerSocket对象
NIO的server端创建的是ServerSocketChannel对象
AIO的server端创建的是AsynchronousServerSocketChannel对象(简称assc)。
对于AIO,assc的accept是异步方法,方法的第二参数就是其回调方法。回调方法就是accept先执行,执行完,后续的逻辑都是在回调函数中实现,实际上就是类似注册了一个监听方法,就是这个回调方法。第一个accept方法有点类似nio的selector.select();
由于是异步方法,所以主线程中加了while(true)的循环,不加的话,主线程结束,服务端整个就结束了,也就不会有什么回调函数的执行了。
在回调方法中,会获取到AsynchronousSocketChannel对象(简称asc),它跟assc实现了相同的接口。可以看下类图:
在assc的回调方法里面,使用assc.accept(null,this);来实现递归,目的是用当前回调函数的匿名对象继续接收后续的客户端请求。assc的accept参数里的回调函数对象,有点类似NIO的Selector,也是一个多路复用器。
使用asc的对象的read和write分别进行读取客户端的数据以及写会给客户端数据。
转载地址:http://fhcdi.baihongyu.com/