netty对于拆包,粘包处理基本有两种方法,一种是基于长度,一种是基于分割符。而基于长度的编解码,就是在header部分定义一个总消息长度或消息体长度,服务端接收到消息后再处理。
这里分析netty中的LineBasedFrameDecoder基于 \n 的分割符处理器。
这个处理器,基本处理过程如下:
1.客户端发送 abc 消息给服务端。
2.服务端首次接收到数据包会将其存入一个堆外内存buffer cumulation中,在发现当前buffer存在 \n 分割符时,直接返回该buffer给下个handler处理。
否则当没有发现 \n时返回null,即暂不处理。
3.客户端继续发送 d\n 给服务端
4.服务端接收到消息后,因为cumulation buffer不为空,所以将新接收到的buffer拷到 cumulation buffer中。
然后进行处理,发列有 \n,则将之前保存的abc及 d交给下一个handler处理。
注:这里的拷贝调用如下:
static void copyMemory(long srcAddr, long dstAddr, long length) { //UNSAFE.copyMemory(srcAddr, dstAddr, length); while (length > 0) { long size = Math.min(length, UNSAFE_COPY_THRESHOLD); UNSAFE.copyMemory(srcAddr, dstAddr, size); length -= size; srcAddr += size; dstAddr += size; } }
这里直接将srcAddr所在地址的缓存,内容大小为length拷到dstAddr所在地址的缓存。
问题:
netty所说的零拷贝,在这里还是有发生堆外内存的拷贝
CompositeChannelBuffer netty 在何时会使用?