你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:杂志经典 / 跟高手学编程
用Java实现非阻塞的HTTP服务器(十)
 

4AcceptHandler

AcceptHandler负责处理接收连结就绪事件。它获得与客户连接的SocketChannel,然后向Selector注册读就绪事件,并且创建了一个RequestHandler,把它作为SelectionKey的附件。当读就绪事件发生,将由这个RequestHandler来处理该事件。例程4AcceptHandler类的源程序:

//例程4  AcceptHandler.java

//此处省略import语句

public class AcceptHandler implements Handler {

  public void handle(SelectionKey key) throws IOException {

    ServerSocketChannel serverSocketChannel=(ServerSocketChannel)key.channel();

//在非阻塞模式下,serverSocketChannel.accept()有可能返回null

//判断socketChannel是否为null,可以使程序更加健壮,避免NullPointerException

    SocketChannel socketChannel = serverSocketChannel.accept();

    if (socketChannel== null)return;

    System.out.println("接收到客户连接,来自:" +

                   socketChannel.socket().getInetAddress() +

                   ":" + socketChannel.socket().getPort());

 

    ChannelIO cio =new ChannelIO(socketChannel, false /*非阻塞模式*/);

    RequestHandler rh = new RequestHandler(cio);

    //注册读就绪事件,把RequestHandler作为附件,

//当这种事件发生时,将由RequestHandler处理该事件

    socketChannel.register(key.selector(), SelectionKey.OP_READ, rh);

  }

}

在以上AcceptHandlerhandle()方法中,还创建了一个ChannelIORequestHandler与它关联。RequestHandler会利用ChannelIO来接收和发送数据。

5RequestHandler

RequestHandler先通过ChannelIO来接收HTTP请求,当接收到了HTTP请求的所有数据,就对HTTP请求数据进行解析,创建相应的Request对象,然后依据客户的请求内容,创建相应的Response对象,最后发送Response对象中包含的HTTP响应数据。为了简化程序,RequestHandler仅仅支持GETHEAD这两种请求方式。例程5RequestHandler的源程序:

//例程5  RequestHandler.java

//此处省略import语句

public class RequestHandler implements Handler {

  private ChannelIO channelIO;

  private ByteBuffer requestByteBuffer = null;  //存放HTTP请求的缓冲区

  private boolean requestReceived = false;  //表示是否已经接收到HTTP请求的所有数据

  private Request request = null;  //表示HTTP请求

  private Response response = null;  //表示HTTP响应

  RequestHandler(ChannelIO channelIO) {

    this.channelIO = channelIO;

  }

 

  /* 接收HTTP请求,如果已经接收到了HTTP请求的所有数据,就返回true,否则返回false */

  private boolean receive(SelectionKey sk) throws IOException {

    ByteBuffer tmp = null;

 

    if (requestReceived)return true;  //如果已经接收到HTTP请求的所有数据,就返回true

 

    //如果已经读到通道的末尾,或者已经读到HTTP请求数据的末尾标志,就返回true

    if ((channelIO.read() < 0) || Request.isComplete(channelIO.getReadBuf())) {

      requestByteBuffer = channelIO.getReadBuf();

      return (requestReceived = true);

    }

    return false;

  }

  推荐精品文章

·2022年10月目录 
·2022年9月目录 
·2022年8月目录 
·2022年7月目录 
·2022年6月目录 
·2022年5月目录 
·2022年4月目录 
·2022年3月目录 
·2022年2月目录 
·2022年1月目录 
·2021年12月目录 
·2021年11月目录 
·2021年10月目录 
·2021年9月目录 

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089