Netty自定义协议要素

  • 魔数:用来判断是否是无效数据包
  • 协议版本号:可以支持协议的升级
  • 序列化算法:消息正文使用哪种序列化方式,可以扩展。例如:protobuf,json,hessian等
  • 指令类型:跟业务相关,例如:登录,注册等
  • 请求序号:为了双工通信,提供异步能力
  • 正文长度
  • 消息正文

防止粘包和半包

设计协议时,虽然我们可以定义如何解析每一个完整的数据包,但是无法保证每次收到的数据包都是完整的。如果出现粘包或半包的问题,就会导致自定义的解析器出错,这就需要Netty提供的如下帧解析器来处理。

// 帧解析器,参数分别表示帧大小,帧内容长度字段的起始偏移,帧内容长度字段本身的长度,内容相比长度字段的偏移量,解析后需要从首部剔除的字节数
// 当发生半包时,帧解析器发现没有获取到完整的帧,就不会把收到的数据向下一个handler传递,知道收到完整的帧才会传递,这就保证了帧的完整性。
public LengthFieldBasedFrameDecoder(
            int maxFrameLength,
            int lengthFieldOffset, int lengthFieldLength,
            int lengthAdjustment, int initialBytesToStrip)
  lengthFieldOffset   = 0
  lengthFieldLength   = 2
  lengthAdjustment    = 0
  initialBytesToStrip = 0 (= do not strip header)
 
  BEFORE DECODE (14 bytes)         AFTER DECODE (14 bytes)
  +--------+----------------+      +--------+----------------+
  | Length | Actual Content |----->| Length | Actual Content |
  | 0x000C | "HELLO, WORLD" |      | 0x000C | "HELLO, WORLD" |
  +--------+----------------+      +--------+----------------+
  
  lengthFieldOffset   = 1 (= the length of HDR1)
  lengthFieldLength   = 2
  lengthAdjustment    = 1 (= the length of HDR2)
  initialBytesToStrip = 3 (= the length of HDR1 + LEN)
 
  BEFORE DECODE (16 bytes)                       AFTER DECODE (13 bytes)
  +------+--------+------+----------------+      +------+----------------+
  | HDR1 | Length | HDR2 | Actual Content |----->| HDR2 | Actual Content |
  | 0xCA | 0x000C | 0xFE | "HELLO, WORLD" |      | 0xFE | "HELLO, WORLD" |
  +------+--------+------+----------------+      +------+----------------+
posted @ 2023-01-28 11:36  金笔书生吕落第  阅读(76)  评论(0编辑  收藏  举报