2012-05-22 54 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