简体   繁体   中英

Java AsynchronousSocketChannel read operation

I'm using the java AsynchronousSocketChannel from nio2 in my project. I'm using oracle jdk 1.7.0_80 on ubuntu 14.04 too.

My project is a server that processes binary data. The code calls the read operation recursively in the completed method of the CompletionHandler anonymous class, like this:

private final CompletionHandler<Integer,AsynchronousSocketChannel> readHandler=new CompletionHandler<Integer,AsynchronousSocketChannel>(){

    @Override
    public void completed(Integer result,AsynchronousSocketChannel attachment) {
        if(result<0){
            attachment.close();
            return;
        }
        attachment.read(swap, attachment, this);
    }
}

Where the variable swap is a ByteBuffer instance.

Apparently, everything works well. But, there is a packet whose total size is 3832 bytes, when the server receive this whole packet, without segments, there is no problem. However, sometimes this packet is divided in two or more parts (TCP segments). eg: The size of first segment is 2896 bytes and the size of second is 936 bytes.

The last segment doesn't have a header, this is breaking my algorithm. I would like know, is there a way to do the API calls the "completed" method only after reading the whole packet?

I have increased the SO_RCVBUF to 64K, but it doesn't work.

I would like know, is there a way to do the API calls the "completed" method only after reading the whole packet?

No, there is no way to do this.

The TCP protocol can break up your stream of bytes in packets of arbitrary size. The application-level protocol that you use on top of TCP must not rely on messages always being sent completely in one TCP packet.

You must design your application-level protocol in such a way that it can deal with messages arriving broken up in packets of arbitrary size.

One common way to do this is to prefix application-level messages by a length field. For example, an application-level message consists of a field of 4 bytes that contain the length of the rest of the message. When you receive a message, you first receive the length, and then you should keep on receiving until you have received that many bytes, which you can then assemble into an application-level message.

The AsynchronousSocketChannel API cannot re-assemble application-level messages automatically for you, because it does not know anything about your application-level protocol.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM