|  e.printStackTrace();            try{                if(key!=null){                    key.cancel();                    key.channel().close();                }            }catch(Exception ex){e.printStackTrace();}         }       }//#while     }//#while   }   public static void main(String args[])throws Exception{     final HttpServer server = new HttpServer();     server.service();   } } 在HttpServer类的service()方法中,当ServerSocketChannel向Selector注册接收连接就绪事件时,设置了一个AcceptHandler附件: serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT,new AcceptHandler()); AcceptHandler类的handle()方法负责处理接收连结就绪事件。当某种事件发生时,HttpServer类的service()方法从SelectionKey中获得Handler附件,然后调用它的handle()方法:  final Handler handler = (Handler)key.attachment();  handler.handle(key);  //处理相关事件 2.具有自动增长的缓冲区的ChannelIO类 ChannelIO对SocketChannel进行了包装,增加了自动增长缓冲区容量的功能。当调用socketChannel.read(ByteBuffer buffer)方法时,如果buffer已满(即position=limit),那么即使通道中还有未接收的数据,read方法也不会读取任何数据,而是直接返回0,表示读到了零个字节。 为了能读取通道中的所有数据,必须保证缓冲区的容量足够大。在ChannelIO类中,有一个requestBuffer变量,它用来存放客户的HTTP请求数据,当requestBuffer剩余容量已经不足5%,并且还有HTTP请求数据未接收,ChannelIO会自动扩充requestBuffer的容量,该功能由resizeRequestBuffer()方法完成。 例程3是ChannelIO类的源程序,它的read()和write()方法利用SocketChannel来接收和发送数据,并且它还提供了实用方法transferTo(),该方法能把文件中的数据发送到SocketChannel中。 //例程3  ChannelIO.java //此处省略import语句 public class ChannelIO {   protected SocketChannel socketChannel;   protected ByteBuffer requestBuffer;  //存放请求数据   private static int requestBufferSize = 4096;     public ChannelIO(SocketChannel socketChannel, boolean blocking)     throws IOException {     this.socketChannel = socketChannel;     socketChannel.configureBlocking(blocking);  //设置模式     requestBuffer = ByteBuffer.allocate(requestBufferSize);   }     public SocketChannel getSocketChannel() {     return socketChannel;   } |