1、粘包拆包的概念
假设客户端分别发送两个数据包D1,D2个服务端,但是发送过程中数据是何种形式进行传播这个并不清楚,分别有下列4种情况:
- 1.服务端一次接受到了D1和D2两个数据包,两个包粘在一起,称为粘包;
- 2.服务端分两次读取到数据包D1和D2,没有发生粘包和拆包;
- 3.服务端分两次读到了数据包,第一次读到了D1和D2的部分内容,第二次读到了D2的剩下部分,这个称为拆包;
- 4.服务器分三次读到了数据部分,第一次读到了D1包,第二次读到了D2包的部分内容,第三次读到了D2包的剩下内容。
2、解决方案
目前主要有四种解决方案:
- 1.消息长度固定,累计读取到消息长度总和为定长Len的报文之后即认为是读取到了一个完整的消息。计数器归位,重新读取,如 FixedLengthFrameDecoder。
- 2.将回车换行符作为消息结束符,如 LineBasedFrameDecoder。
- 3.将特殊的分隔符作为消息分隔符,回车换行符是他的一种,如 DelimiterBasedFrameDecoder。
- 4.通过在消息头定义长度字段来标识消息总长度,如 LengthFieldBasedFrameDecoder。
实际上,我还看到有人自定义编解码器,直接按照指定的格式写 msg 的 length、byte 来编码发送,在解码的时候,首先读取 length,然后再读取 length 长度的 byte 解码之类的。
对于小白来说,我觉得选择编解码器之前,首先网上搜搜 netty 现成的编解码器能不能满足需求,直接使用即可,不行再去慢慢写或者调试自己的编解码器。比如,你要使用 netty 作为 http 服务器,那么集成 netty 现成的 http 编解码器,使用 http 的消息。










网友评论