关于Netty半包、粘包问题的解决思路

粘包半包原因

因为 TCP 是面向连接的传输协议,TCP 传输的数据是以流的形式,而流数据是没有明确的开始结尾边界,所以 TCP 也没办法判断哪一段流属于一个消息

粘包的主观原因:

  • 发送方每次写入数据 < 套接字(Socket)缓冲区大小;
  • 接收方读取套接字(Socket)缓冲区数据不够及时。

半包的主观原因:

  • 发送方每次写入数据 > 套接字(Socket)缓冲区大小;
  • 发送的数据大于协议的 MTU (Maximum Transmission Unit,最大传输单元),因此必须拆包。

一些客观原因:

1.服务器处理间隔超过客户端的发送间隔,最常见。

2.客户端几乎同一时间发送了数据过来,本质上也是服务器还没来的及处理,就又来新的数据。

3.绝对时间相同发送数据,多见于分布式。

本质上是ByteBuf 来不及处理,把ByteBuf比喻成嘴,就像一张嘴吃着白菜还没来得及咽下去又来了一根黄瓜,白菜黄瓜一起在嘴里吃就是粘包。嘴吧放不下了,只能咬下半根黄瓜,那就造成剩下的半根黄瓜不完整(半包)。所以粘包半包一方面取决于嘴(Bytebuf)的容量,能否在服务器响应时间内,处理(吃)足够多的(食物)数据。但又要考虑一旦没食物(数据),空有一张大嘴在不断咀嚼会不会过于浪费的问题。

目前我个人总结的处理办法有6种:

1.短链接

发送完毕,立即断开,每次都要新建连接。

适用于不频繁使用的数据发送,但是使用短连接后就不能发挥出NIO的优势。

2.FixedLengthFrameDecoder

填补空白法,但是要确定最大长度,比较耗费空间。

适用于每次传输的数据长度差异较小的情况,但只是减少浪费而已。

3.LineBasedFrameDecoder

根据换行符切分,接收到字符后要每一个字节去查分隔符,效率太低。

适用于传输数据量较短的情况,数据越短寻找数据的时间就短。

4.DelimiterBasedFrameDecoder

根据分隔符切分...,和上一条没太大区别,只是可以自定义分隔符。

5.LengthFieldBaseFrameDecoder

长度域,发送包之前加上一个长度字段、一个类型字段。每次只获取固定长度固定类型的数据,其他的都不会被处理。最常用的处理器。但如果数据量极小的情况下,会浪费资源。

6.客户端线程睡眠

使客户端在发送前睡眠一段时间,时间需要大于服务器的处理时间。

造成效率降低,但是在数据实时性要求不高,而且只在固定时间大量通信的情况下成本最低。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值