重传包括超时重传、快速重传、带选择确认的重传(SACK)、重复 SACK 四种。
一、TCP重传机制
1.1超时重传
超时重传,是 TCP 协议保证数据可靠性的另一个重要机制,其原理是在发送某一个数据以后就开启一个计时器,在一定时间内如果没有得到发送的数据报的 ACK 报文,那么就重新发送数据,直到发送成功为止。
1.2快速重传
TCP 还有另外⼀种快速重传(Fast Retransmit)机制,它不以时间为驱动,⽽是以 数据驱动重传。
它不以时间驱动,而是以数据驱动。它是基于接收端的反馈信息来引发重传的。可以用它来解决超时重发的时间等待问题
1.3带选择确认的重传(SACK)
为了解决应该重传多少个包的问题? TCP 提供了带选择确认的重传(即 SACK,Selective Acknowledgment)。
SACK 机制就是,在快速重传的基础上,接收方返回最近收到报文段的序列号范围,这样发送方就知道接收方哪些数据包是没收到的。这样就很清楚应该重传哪些数据包。
1.4重复 SACK(D-SACK)
D-SACK,英文是 Duplicate SACK,是在 SACK 的基础上做了一些扩展,主要用来告诉发送方,有哪些数据包,自己重复接受了。
DSACK 的目的是帮助发送方判断,是否发生了包失序、ACK 丢失、包重复或伪重传。让 TCP 可以更好的做网络流控。
二、TCP 的粘包和拆包
2.1 什么是TCP粘包和拆包
TCP 是面向流,没有界限的一串数据。TCP 底层并不了解上层业务数据的具体含义,它会根据 TCP 缓冲区的实际情况进行包的划分,所以在业务上认为,一个完整的包可能会被 TCP 拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送,这就是所谓的 TCP 粘包和拆包问题。
2.2 为什么会产生粘包和拆包呢?
要发送的数据小于 TCP 发送缓冲区的大小,TCP 将多次写入缓冲区的数据一次发送出去,将会发生粘包;
接收数据端的应用层没有及时读取接收缓冲区中的数据,将发生粘包;
要发送的数据大于 TCP 发送缓冲区剩余空间大小,将会发生拆包;
待发送数据大于 MSS(最大报文长度),TCP 在传输前将进行拆包。即 TCP 报文长度 - TCP 头部长度 > MSS。
2.3 怎么解决呢?
发送端将每个数据包封装为固定长度
在数据尾部增加特殊字符进行分割
将数据分为两部分,一部分是头部,一部分是内容体;其中头部结构大小固定,且有一个字段声明内容体的大小。