NIO异步通信2
要了解NIO的机制,首先要熟悉Channel和Selector.举个例子来描述Channel和Selector:Channel类似一个管道,Selector汇聚了多个管道,当管道中来水之后,Selector会感知到,将水送到对应的家庭中(每个家庭都有一个Channel),这就是Reactor模式的典型应用。图3.1 SelectableChannel的类图如下: 启动服务端的典型步骤如下:1)打开ServerSocketChannel,绑定本机的服务端口,设置通信方式为异步非阻塞,同时设置地址重用://打开socket通道ServerSocketChannel acceptorSvr = ServerSocketChannel.open(); //绑定端口acceptorSvr.socket().bind(new InetSocketAddress(port)); //设置为非阻塞方式acceptorSvr.configureBlocking(false);//重用地址acceptorSvr.socket().setReuseAddress(true);2)将打开的ServerSocketChannel注册到Reactor的选择器监听消息://打开多路复用器Selector selector = Selector.open();//注册到复用器上acceptorSvr. register(selector, SelectionKey.OP_ACCEPT, handler); 3)首次接收到客户端的请求消息,做相关的登陆消息处理(例如登陆认证),修改状态为监听读操作:int count = selector.select();if (count > 0){Iterator<SelectionKey> it = selector.selectedKeys().iterator();while (it.hasNext()) { key = it.next(); it.remove(); handleInput(key); }}// handleInput(key)的实现: if (key.isAcceptable()) { // 集群且异步调度情况下,使用该机制,监听客户端的连接是否到达 acceptorSvr. register(selector, SelectionKey.OP_READ, handler); }4)客户端登陆成功之后,只需要监听读写操作完成通信处理: if (key.isReadable()) { // 读消息,多态方式,根据注册的handler进行分别处理 IHandler handler = (IHandler)key.attachment(); //读消息到缓冲区int count = channel.read(receivedBuffer);}5)写操作很简单,直接调用Channel的write接口:if (key. isWritable ()) { // 写消息,多态方式,根据注册的handler进行分别处理IHandler handler = (IHandler)key.attachment(); int n = handler.getChannel().write(buffer); //非阻塞写}