How to read a request using CompletionHandlers and a ByteBuffer smaller than the request?

≡放荡痞女 提交于 2019-11-29 21:11:26

问题


I am using Java 7 and AsynchronousSocketChannel. I would like to read a request (e.g. HTTP POST) but I'm struggling to come up with a nice solution to read the full request, if it's bigger than the size of the ByteBuffer I'm using. E.g. if the ByteBuffer is 4048 bytes and the HTTP POST contains an image that is larger than 4kB.

Is there any nice recursive solution or loop for this?

Here is my code for reading requests:

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();
        }

    });
}

And where I have written:

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

it look like a good place for code reuse, but I can't come up with a nice solution. Is there any way I can reuse the CompletionHandler here? Any suggestion for reading a full request with a limited ByteBuffer?

I would like to solve this in an non-blocking and asynchronous way.


回答1:


The completed method is called asynchronously from a thread managed by java when a block of data is read. To reuse the CompletionHandler:

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

The java guys recommend that when you finish the read operation (the else block) you should use another thread context.

This is the document that says to avoid blocking and long lived operations inside a CompletionHandler, look in page 33 http://openjdk.java.net/projects/nio/presentations/TS-4222.pdf



来源:https://stackoverflow.com/questions/10698689/how-to-read-a-request-using-completionhandlers-and-a-bytebuffer-smaller-than-the

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!