概念
TCP 是以流的方式来处理数据,所以会导致粘包 / 拆包。
-
拆包:一个完整的包可能会被 TCP 拆分成多个包进行发送。
-
粘包:也可能把小的封装成一个大的数据包发送。
原因
-
应用程序写入的字节大小大于套接字发送缓冲区的大小,会发生拆包现象。而应用程序写入数据小于套接字缓冲区大小,网卡将应用多次写入的数据发送到网络上,这将会发生粘包现象。
-
待发送数据大于 MSS(最大报文长度),TCP 在传输前将进行拆包。
-
以太网帧的 payload(净荷)大于 MTU(默认为 1500 字节)进行 IP 分片拆包。
-
接收数据端的应用层没有及时读取接收缓冲区中的数据,将发生粘包。
解决
在 Netty 中,提供了多个 Decoder 解析类,如下:
-
① FixedLengthFrameDecoder ,基于固定长度消息进行粘包拆包处理的。
-
② LengthFieldBasedFrameDecoder ,基于消息头指定消息长度进行粘包拆包处理的。
-
③ LineBasedFrameDecoder ,基于换行来进行消息粘包拆包处理的。
-
④ DelimiterBasedFrameDecoder ,基于指定消息边界方式进行粘包拆包处理的。
实际上,上述四个 FrameDecoder 实现可以进行规整:
-
① 是 ② 的特例,固定长度是消息头指定消息长度的一种形式。
-
③ 是 ④ 的特例,换行是于指定消息边界方式的一种形式。
在生产中是通过自定义协议处理的,在协议的开始有startTag字段,结束有endTag字段。