Netty作为网络应用框架,在网络上的各个应用之间不断进行数据交互。而网络数据交换的基本单位是字节,而java应用传输又是POJO,这就要序列化成字节再网络上传输。Netty是使用TCP/UDP在互联网上传输数据,由于Netty异步的特性,当使用TCP时,不可避免就会出现TCP粘包/拆包现象。对于TCP粘包/拆包,业界公开的有一下几种方法:
- 使用分隔符分割
- 使用定长的消息,不足补空格之类的
- 在传输的消息上制定长度
Netty使用ByteToMessageDecoder进行读半包处理,ByteToMessageDecoder是一个抽象类,继承于ChannelInboundHandlerAdapter,首先看下ByteToMessageDecoder的属性:
cumulation-用来保存累计读取到的字节
cumulator-累计器,把从channel获取到的字节累计起来有两种实现,首先看下定义
Cumulator只有一个方法 cumulate(),用于累计字节,该接口有两个实现,默认使用的是MERGE_CUMULATOR
public static final Cumulator MERGE_CUMULATOR = new Cumulator() {
@Override
public ByteBuf cumulate(ByteBufAllocator alloc, ByteBuf cumulation, ByteBuf in) {
final ByteBuf buffer;
if (cumulation.writerIndex() > cumulation.maxCapacity() - in.readableBytes()
|| cumulation.refCnt() > 1 || cumulation.isReadOnly()) {
// Expand cumulation (by replace it) when either there is not more room in the buffer
// or if the refCnt is greater then 1 which may happen when the user use slice().retain() or
// duplicate().retain() or if its read-only.
//
// See:
// - https://github.com/netty/netty/issues/2327
// - https://github.com/netty/netty/issues/1764
buffer = expandCumulation(alloc, cumulation, in.readableBytes());
} else {
buffer = cumulation;
}
buffer.writeBytes(in);
in.release();
return buffer;
}
};
in 参数表示新读取到的数据,该方法只是简单的判断了下是否要扩容,是的话就扩容,然后把新读取到的数据写入进来,释放in的内存,在返回新ByteBuf。另外一个实现是COMPOSITE_CUMULATOR
public s