JanWong,粘包

怎么解决TCP网络传输「粘包」问题?
【JanWong,粘包】

JanWong,粘包


TCP粘包是指发送方发送的多个数据包到接收方后粘连在一起 , 导致数据包不能完整的提现发送的数据 。TCP协议TCP是一个面向连接的传输层协议 , 不属于ISO制定的协议集 。TCP协议在商业界和工业界的成功应用 , 使它成为事实上的网络标准 , 广泛应用于各种网络主机间的通信 。TCP目标是为用户提供可靠的端到端连接 , 保证信息有序无误的传输 。
TCP为确保可靠性采用了数据编号、校验和计算、数据确认等一系列措施 。TCP对传送的每个数据字节都进行编号 , 并请求接收方回传确认信息(ACK) 。发送方如果在规定的时间内没有收到数据确认 , 就重传该数据 。数据编号使接收方能够处理数据的失序和重复问题 。数据误码问题通过在每个传输的数据段中增加校验和予以解决 , 接收方在接收到数据后检查校验和 , 若校验和有误 , 则丢弃该有误码的数据段 , 并要求发送方重传 。
流量控制也是保证可靠性的一个重要措施 , 若无流控 , 可能会因接收缓冲区溢出而丢失大量数据 , 导致许多重传 , 造成网络拥塞恶性循环 。TCP采用可变窗口进行流量控制 , 由接收方控制发送方发送的数据量 。这些可靠性保障措施为用户提供了高可靠性的网络传输服务 , 但也影响了传输效率 。在实际工程应用中 , 只有关键数据的传输才采用TCP , 而普通数据的传输一般采用高效率的UDP 。
UDP不会出现粘包问题 。UDP支持的是一对多的模式 , 不会使用块的合并优化算法 , 所以接收端的skbuff(套接字缓冲区)采用了链式结构来记录每一个到达的UDP包 , 在每个UDP包中就有了消息头(包含消息来源地址 , 端口等信息) , 接收端很容易就能进行区分处理了 。粘包出现原因出现粘包现象的原因有很多方面 , 它既可能由发送方造成的 , 也可能是由接收方造成的 。
发送方原因TCP需要尽可能高效和可靠 , 默认采用Nagle算法 , 发送方往往要收集到足够多的数据后合并相连的小数据包 , 才发送一包数据 , 这样接收方就收到了粘包数据 。但接收方并不知晓发送方合并数据包 , 并数据包的合并在TCP协议中是没有分界线的 , 就会导致接收方不能还原其本来的数据包 。接收方原因TCP是基于“流”的 。
网络传输数据的速度可能会快过接收方处理数据的速度 , 这时候就会导致 , 接收方在读取缓冲区时 , 缓冲区存在多个数据包 。在TCP协议中接收方是一次读取缓冲区中的所有内容 , 就不能反映原本的数据信息 。粘包情况有两种:一种是粘在一起的包都是完整的数据包;一种是粘在一起的包有不完整的包;不是所有的粘包现象都需要处理如果传输的数据为不带结构的连续流数据(如文件传输) , 就不必把粘连的包分开(简称分包) 。
但实际工程应用中一般为带结构的数据 , 这时就需要做分包处理 。在处理定长结构数据的粘包问题时 , 分包算法比较简单;在处理不定长结构数据的粘包问题时 , 分包算法就比较复杂 。特别是粘在一起的包有不完整的包的粘包情况 , 一包数据内容被分在了两个连续的接收包中 , 处理起来难度较大 。实际工程应用中应尽量避免出现粘包现象 。为了避免粘包现象 , 可采取以下几种措施:(1)发送方引起的粘包可通过编程设置来避免 。

推荐阅读