netty的基本概念-TCP粘包和拆包

本文探讨了TCP协议下粘包和半包问题的成因,以及常见的解决策略,如定长消息、分隔符标记和协议头部长度。重点介绍了Netty如何通过解析机制避免半包影响,确保数据完整传递。

TCP 粘包/拆包

TCP 是一个“流”协议,所谓流,就是没有界限的一长串二进制数据。TCP 作为传输层协议并不不了解上层业务数据的具 体含义,它会根据 TCP 缓冲区的实际情况进行数据包的划分,所以在业务上认为是一个完整的包,可能会被 TCP 拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送,这就是所谓的 TCP 粘包和拆包问题。 同样, 在 Netty 的编码器中, 也会对半包和粘包问题做相应的处理。什么是半包, 顾名思义, 就是不完整的数据包, 因为 Betty 在轮询读事件的时候, 每次将 channel 中读取的数据, 不一定是一个完整的数据包, 这种情况, 就叫半包。粘包同 样也不难理解, 如果Client往 Server发送数据包, 如果发送频繁很有可能会将多个数据包的数据都发送到通道中, 如果在 server 在读取的时候可能会读取到超过一个完整数据包的长度, 这种情况叫粘包。有关半包和粘包, 如下图所示:

粘包问题的解决策略

由于底层的 TCP 无法理解上层的业务数据,所以在底层是无法保证数据包不被拆分和重组的,这个问题只能通过上层的应用协议栈设计来解决。业界的主流协议的解决方案,可以归纳如下:

\1. 消息定长,报文大小固定长度,例如每个报文的长度固定为 200 字节,如果不够空位补空格;

\2. 包尾添加特殊分隔符,例如每条报文结束都添加回车换行符(例如 FTP 协议)或者指定特殊字符作为报文分隔符, 接收方通过特殊分隔符切分报文区分;

\3. 将消息分为消息头和消息体,消息头中包含表示信息的总长度(或者消息体长度)的字段;

\4. 更复杂的自定义应用层协议。

Netty 对半包的或者粘包的处理其实也很简单, 通过之前的学习, 我们知道, 每个 handler 是和 channel 唯一绑定的, 一个 handler 只对应一个 channel, 所以将 channel 中的数据读取时候经过解析, 如果不是一个完整的数据包, 则解析失 败, 将这块数据包进行保存, 等下次解析时再和这个数据包进行组装解析, 直到解析到完整的数据包, 才会将数据包进 行向下传递

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值