2012-05-22 49 views
4

我正在使用Java 7和AsynchronousSocketChannel。我想阅读一个请求(例如HTTP POST),但如果它大于我使用的ByteBuffer的大小,我很难想出一个很好的解决方案来阅读完整的请求。例如。如果ByteBuffer是4048字节,并且HTTP POST包含大于4kB的图像。如何使用小于请求的CompletionHandlers和ByteBuffer读取请求?

有没有什么好的递归解决方案或循环呢?

这是我读请求的代码:

public void readRequest(final AsynchronousSocketChannel ch) { 
    final ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE); 
    final StringBuilder strBuilder = new StringBuilder(); 
    final CharsetDecoder decoder = Charset.forName("US-ASCII").newDecoder(); 

    ch.read(buffer, null, new CompletionHandler<Integer, Void>() { 

     public void completed(Integer bytes, Void att) { 

      buffer.flip();       
      try { 
       decoder.reset(); 
       strBuilder.append(decoder.decode(buffer).toString()); 
      } catch (CharacterCodingException e) { 
       e.printStackTrace(); 
      }   
      buffer.clear();   

      // More data to read or send response 
      if(bytes != -1) { 

       // More data to read 
       ch.read(...); 

      } else { 

       // Create and send a response 

      } 
     } 

     public void failed(Throwable exc, Void att) { 
      exc.printStackTrace(); 
     } 

    }); 
} 

在哪里我已经写:

// More data to read 
ch.read(...); 

它看起来像代码重用的好地方,但我不能想出一个好的解决方案有什么方法可以在这里重用CompletionHandler吗?任何建议阅读有限的ByteBuffer完整的请求?

我想以非阻塞和异步的方式解决这个问题。

回答

4

completed方法在读取数据块时由java管理的线程异步调用。要重用CompletionHandler:

// More data to read 
ch.read(buffer, null, this); //here you pass the same CompletionHandler you are using 

的java的人建议,当你完成读操作时(else块),你应该使用其他线程上下文。

这是说,为了避免阻塞CompletionHandler内部和长寿命的操作,看在33页http://openjdk.java.net/projects/nio/presentations/TS-4222.pdf

+0

所以下面这个建议的文件,这将是一个坏主意,叫AsynchronousServerSocketChannel的从完成处理程序接受的方法? – sloven