包是什么
包的定义:客户端和服务端在发送数据的过程中,每次会以一个数据包的形式进行数据传输,比如登录会发送一个包含账号密码和登录行为标识的包,下线会发送一个包含下线行为标志的包,所以包是以业务维度界定的。
拆包和粘包是什么
粘包的定义:将两个包粘在一起。
拆包的定义:粘包发生后,为了正确的界定包的边界来进行相应的业务逻辑处理,需要对粘在一起的包进行拆解。
所以拆包粘包的定义就是,客户端和服务端会接收到不完整包信息,需要对其进行拆分。
为什么会发生拆包和粘包
Netty在传输层使用的协议是TCP,为了高效的发送数据,每次会以缓冲池为单位进行数据的发送,而我们的数据包,是以业务维度界定,TCP无法理解。
当缓冲池剩余大小 < 单个包大小,客户端会发生拆包,服务端会发生对应的粘包。
当MSS(最大报文长度) < 单个包大小,客户端会发生拆包,服务端会发生对应的粘包。
当缓冲池剩余大小 > 单个包大小,客户端会发生粘包,服务端会发生对应的拆包。
如何解决拆包粘包
-
固定长度的拆包器 FixedLengthFrameDecoder
如果你的应用层协议非常简单,每个数据包的长度都是固定的,比如 100,那么只需要把这个拆包器加到 pipeline 中,Netty 会把一个个长度为 100 的数据包 (ByteBuf) 传递到下一个 channelHandler。 -
行拆包器 LineBasedFrameDecoder
从字面意思来看,发送端发送数据包的时候,每个数据包之间以换行符作为分隔,接收端通过 LineBasedFrameDecoder 将粘过的 ByteBuf 拆分成一个个完整的应用层数据包。 -
分隔符拆包器 DelimiterBasedFrameDecoder
DelimiterBasedFrameDecoder 是行拆包器的通用版本,只不过我们可以自定义分隔符。 -
基于长度域拆包器 LengthFieldBasedFrameDecoder
最后一种拆包器是最通用的一种拆包器,只要你的自定义协议中包含长度域字段,均可以使用这个拆包器来实现应用层拆包。
网友评论