微建网站,有没有网站做lol网站的,重庆市建设厅网站,广州市网站建设科技文章目录 概述粘包拆包发生场景解决TCP粘包和拆包问题的常见方法Netty对粘包和拆包问题的处理小结 概述
TCP的粘包和拆包问题往往出现在基于TCP协议的通讯中#xff0c;比如RPC框架、Netty等 TCP 粘包/拆包 就是你基于 TCP 发送数据的时候#xff0c;出现了多个字符串“粘”… 文章目录 概述粘包拆包发生场景解决TCP粘包和拆包问题的常见方法Netty对粘包和拆包问题的处理小结 概述
TCP的粘包和拆包问题往往出现在基于TCP协议的通讯中比如RPC框架、Netty等 TCP 粘包/拆包 就是你基于 TCP 发送数据的时候出现了多个字符串“粘”在了一起或者 一个字符串被“拆”开的问题。 TCP粘包和拆包是指在使用TCP协议进行数据传输时发送方发送的数据包与接收方接收的数据包之间出现了不符合预期的粘连或拆分情况。 TCP粘包TCP粘包指的是发送方在一次发送中将多个逻辑上独立的数据包粘合成一个大的数据包发送而接收方可能会将这个大的数据包误认为是多个小的数据包。这种情况下接收方需要根据自身的接收缓冲区大小和数据包的边界进行数据的解析容易导致数据解析错误或混乱。 TCP拆包TCP拆包指的是发送方在一次发送中将一个逻辑上独立的数据包拆分成多个小的数据包发送而接收方可能会将这些小的数据包合并成一个大的数据包。这种情况下接收方需要对接收到的数据进行拆包处理以获取完整的数据包。 1、要发送的数据大于 TCP 发送缓冲区剩余空间大小将会发生拆包。 2、待发送数据大于 MSS最大报文长度TCP 在传输前将进行拆包。 3、要发送的数据小于 TCP 发送缓冲区的大小TCP 将多次写入缓冲区的数据一次发送出去将会发生粘包。 4、接收数据端的应用层没有及时读取接收缓冲区中的数据将发生粘包。
粘包拆包发生场景
因为TCP是面向流没有边界而操作系统在发送TCP数据时会通过缓冲区来进行优化例如缓冲区为1024个字节大小。 如果一次请求发送的数据量比较小没达到缓冲区大小TCP则会将多个请求合并为同一个请求进行发送这就形成了粘包问题。 如果一次请求发送的数据量比较大超过了缓冲区大小TCP就会将其拆分为多次发送这就是拆包。 关于粘包和拆包可以参考下图的几种情况
上图中演示了以下几种情况 ● 正常的理想情况两个包恰好满足TCP缓冲区的大小或达到TCP等待时长分别发送两个包 ● 粘包两个包较小间隔时间短发生粘包合并成一个包发送 ● 拆包一个包过大超过缓存区大小拆分成两个或多个包发送 ● 拆包和粘包Packet1过大进行了拆包处理而拆出去的一部分又与Packet2进行粘包处理。
解决TCP粘包和拆包问题的常见方法
消息长度固定发送方在每个数据包中添加固定长度的消息头用于表示后续数据包的长度。接收方根据消息头中的长度信息来正确解析数据包从而避免粘包和拆包问题。特殊字符分隔发送方在数据包之间插入特殊字符如换行符或其他预先约定好的字符作为分隔符接收方根据特殊字符来切分数据包。这种方法需要保证特殊字符不会出现在实际数据中否则会引起解析错误。消息头消息体发送方在每个数据包中添加消息头消息头包含实际数据的长度信息。接收方首先读取消息头中的长度信息然后按照长度读取对应数量的字节作为实际数据。使用消息边界在传输过程中发送方和接收方约定好数据包的边界例如每个数据包以换行符结尾。接收方根据约定的边界来正确解析数据包从而避免粘包和拆包问题。引入应用层协议在TCP之上构建应用层协议该协议负责定义数据包的格式和解析规则。通过自定义协议来规范数据包的传输和解析从而有效解决粘包和拆包问题。 选择哪种方法来解决TCP粘包和拆包问题取决于具体的应用场景和需求。需要注意的是在实际开发中可能需要综合应用多种方法来解决复杂的粘包和拆包情况。 ● 发送端将每个包都封装成固定的长度比如100字节大小。如果不足100字节可通过补0或空等进行填充到指定长度 ● 发送端在每个包的末尾使用固定的分隔符例如\r\n。如果发生拆包需等待多个包发送过来之后再找到其中的\r\n进行合并例如FTP协议 ● 将消息分为头部和消息体头部中保存整个消息的长度只有读取到足够长度的消息之后才算是读到了一个完整的消息 ● 通过自定义协议进行粘包和拆包的处理。
Netty对粘包和拆包问题的处理
Netty对解决粘包和拆包的方案做了抽象提供了一些解码器Decoder来解决粘包和拆包的问题。如 ● LineBasedFrameDecoder以行为单位进行数据包的解码 ● DelimiterBasedFrameDecoder以特殊的符号作为分隔来进行数据包的解码 ● FixedLengthFrameDecoder以固定长度进行数据包的解码 ● LenghtFieldBasedFrameDecode适用于消息头包含消息长度的协议最常用 基于Netty进行网络读写的程序可以直接使用这些Decoder来完成数据包的解码。对于高并发、大流量的系统来说每个数据包都不应该传输多余的数据所以补齐的方式不可取LenghtFieldBasedFrameDecode更适合这样的场景。
小结
TCP协议粘包拆包问题是因为TCP协议数据传输是基于字节流的它不包含消息、数据包等概念需要应用层协议自己设计消息的边界即消息帧Message Framing。如果应用层协议没有使用基于长度或者基于终结符息边界等方式进行处理则会导致多个消息的粘包和拆包。 虽然很多框架中都有现成的解决方案比如Netty但底层的原理我们还是要清楚的而且还要知道有这么会事才能更好的结合场景进行使用。