目录
分布式之Netty介绍与实战(四)–Netty编解码编程实战
- 半包粘包问题示例与分析
- Netty半包粘包问题解决
- Netty编解码器分析
半包粘包问题示例与分析
TCP/IP协议
面向“流”协议 MSS: Maxitum Segment Size
最大分段大小,表示TCP数据包每次能够传输的最大数据分段 发送方/接收方缓冲区 Nagle算法(顺序出现)
粘包/拆包解决思路
基本思路就是不断从TCP缓冲区中读取数据,每次读取完都需要判断是否是一个完整的数据包
若当前读取的数据不足以拼接成一个完整的业务数据包,那就保留该数据,继续从tcp缓冲区中读取,直到得到一个完整的数据包
定长、分隔符、基于长度变长包
若当前读到的数据加上已经读取的数据足够拼接成一个数据包,那就将已经读取的数据拼接上本次读取的数据,够成一个完整的业务数据包传递到业务逻辑,多余的数据仍然保留,以便和下次读到的数据尝试拼接
Netty半包粘包问题解决
Netty常用编解码器
- LineBasedFrameDecoder
- 回车换行解码器 配合StringDecoder
- DelimiterBasedFrameDecoder
- 分隔符解码器
- FixedLengthFrameDecoder
- 固定长度解码器
- LengthFieldBasedFrameDecoder
- 基于’长度’解码器(私有协议最常用)
Netty拆包的基类
- ByteToMessageDecoder
- 自解析
- LengthFieldPrepender
- 长度编码器
Netty拆包的基类 - ByteToMessageDecoder
内部维护了一个数据累积器cumulation,每次读取到数据都会不断累加,然后尝试对累加到的数据进行拆包,拆成一个完整的业务数据包
每次都将读取到的数据通过内存拷贝的方式, 累积到cumulation中 调用子类的decode方法对累积的数据尝试进行拆包
基于包头不固定长度的解码器
基于包头不固定长度的解码器:
LengthFieldBasedFrameDecoder 参数说明
maxFrameLength:包的最大长度
lengthFieldOffset:长度属性的起始位(偏移位),包中存放长度属性字段的起始位置
lengthFieldLength:长度属性的长度
lengthAdjustment:长度调节值,在总长被定义为包含包头长度时,修正信息长度
initialBytesToStrip:跳过的字节数,根据需要跳过lengthFieldLength个字节,以便接收端直接接受到不含“长度属性”的内容
LengthFieldPrepender 编码器
参数说明 lengthFieldLength:长度属性的字节长度
lengthIncludesLengthFieldLength:false,长度字节不算在总长度中,true,算到总长度中
Netty 编解码
编解码器的作用就是讲原始字节数据与自定义的消息对象进行互转
Decoder(解码器)
Encoder(编码器)
支持业界主流的序列化框架
Protobuf
Jboss Marshalling
Java Serialization