参考资料 :小林Coding、阿秀、代码随想录
一、TCP拥塞控制⭐
1. 慢启动 -- Slow Start
慢启动是指TCP连接刚建立,一点一点地提速,试探一下网络的承受能力,以免直接扰乱了网络通道的秩序。
慢启动算法:
- 初始拥塞窗口 cwnd = 1,表明可以传一个MSS大小的数据。
- 每当发送方收到一个ACK,cwnd大小加一。
- 每当过了一个往返延迟时间RTT(Round-Trip Time),cwnd大小直接翻倍,乘以2,呈指数让升。
- 慢启动拥有一个ssthresh(slow start threshold)门限,当 cwnd >= ssthresh 时,就会进入拥塞避免算法
2. 拥塞避免 -- Congestion Avoidance
当拥塞窗口大小cwnd大于等于慢启动阈值ssthresh后,就进入拥塞避免算法。算法如下:
- 收到一个ACK,则 cwnd = cwnd + 1 / cwnd
- 每当过了一个往返延迟时间 RTT,cwnd 大小加一
过了慢启动阈值后,拥塞避免算法可以避免窗口增长过快导致窗口拥塞 ,而是缓慢的增加调整到网络的最佳值。
举个🌰:
"拥塞避免"是说在拥塞避免阶段把拥塞窗口控制为按线性规律增长,使网络比较不容易出现拥塞。
3. 拥塞发生
TCP拥塞控制 默认认为网络丢包是由于网络拥塞导致 的,所以一般的TCP拥塞控制算法以丢包为网络进入拥塞状态的信号 。对于丢包有两种判定方式,一种是超时重传RTO (Retransmission Timeout),另一个是快速重传(收到三个重复确认ACK)。(重传机制具体介绍见第三部分)
1)超时重传RTO
超时重传是TCP协议保证数据可靠性的一个重要机制,其原理是在发送一个数据以后就开启一个计时器 ,在一定时间内如果没有得到发送数据报的ACK报文,那么就重新发送数据,直到发送成功为止。
- 由于发生丢包,将慢启动阈值ssthresh设置为当前拥塞窗口cwnd的一半,即 ssthresh = cwnd / 2
- cwnd重置为1 (恢复为 cwnd 初始化值)
- 进入慢启动过程
2)快速重传
如果发送端接收到3个以上的重复ACK,TCP就意识到数据发生丢失,需要重传。这个机制不需要等到重传定时器超时,所以叫快速重传。
- cwnd大小缩小为当前的一半
- ssthresh设置为缩小后的cwnd大小
- 然后进入快速恢复算法Fast Recovery。
4. 快速恢复 ------ Fast Recovery
TCP Tahoe是早期的算法,所以没有快速恢复算法,而Reno算法有。在进入快速恢复之前,cwnd 和 ssthresh 已经被更改为原有 cwnd 的一半。快速恢复算法的逻辑如下:
-
拥塞窗口 cwnd = cwnd + 3 MSS,加 3 MSS的原因是因为收到3个重复的ACK。
-
重传丢失的数据包。
-
如果再收到重复的ACK,那么cwnd大小增加一。
-
如果收到新的ACK,表明重传的包成功了,那么退出快速恢复算法。将cwnd设置为ssthresh,然后进入拥塞避免算法。
二、TCP可靠传输
TCP协议保证数据传输可靠性的方法主要有:校验和、序列号、确认应答、超时重传、连接管理、流量控制、拥塞控制。
-
数据校验:TCP报文头有校验和,采用CRC校验全部数据;
-
序列号和确认应答:TCP通过给每个发送的数据段分配一个序号 ,以及使用确认机制ACK来跟踪数据的传输与接收。接收方会确认已经成功接收的数据,发送方则根据收到的确认确定哪些数据已经被成功传输,哪些需要重新发送。
-
超时和重传:TCP使用超时机制来检测是否发生数据包丢失 ,如果发送方在一定时间内未收到确认,就认为数据包丢失,并触发响应的重传。这确保及时某个数据包在传输过程中丢失,最终仍能够被成功传递。
-
连接管理:通信前确认通信实体的存在。(具体见【面试八股总结】传输控制协议TCP(一)-CSDN博客)
-
流量控制:TCP使用滑动窗口机制进行流量控制,确保发送方不会以高于接收方处理速度的速率发送数据,这有助于防止接收方缓冲溢出,提高整个通信链路效率,防止数据包丢失。(具体见【面试八股总结】传输控制协议TCP(二)-CSDN博客)
-
拥塞控制:TCP还具有拥塞控制机制,通过动态调整发送速率以适应网络状况。当网络出现拥塞时,通过拥塞窗口,减缓发送速率,防止进一步加剧拥塞。(具体见第一部分)
三、TCP重传机制
1. 超时重传
TCP在发送数据时,会设定一个定时器,当超过指定的时间后,没有收到对方的 ACK
确认应答报文,就会重发该数据,也就是超时重传。TCP 会在以下两种情况发生超时重传:
- 数据包丢失
- 确认应答丢失
超时重传时间RTO(Retransmission Timeout)
- 当超时时间 RTO 较大时,网络的空闲时间增大,降低了传输效率。
- 当超时时间 RTO 较小时,会引起很多报文段的不必要的重传,使网络负荷增大。
TCP 采用了一种自适应算法,它记录一个报文段发出的时间,以及收到相应的确认的时间。这两个时间之差就是报文段的往返时延RTT(Round-Trip Time)。
TCP保留RTT的一个加权平均往返时间RTTS(又称为平滑的往返时间)。
第一次测量到 RTT 样本时,RTTS 值就取为所测量到的 RTT 样本值。以后每测量到一个新的 RTT 样本,就按下式重新计算一次 RTTS:
新的RTTs = (1 - α) × (旧的 RTTs) + α ×(新的 RTT 样本)
式中,0 < α < 1。若 α 很接近于零,表示 RTT 值更新较慢。若选择α接近于 1,则表示 RTT 值更新较快。
2. 快速重传
快速重传(Fast Retransmit)机制 ,不以时间为驱动,而是以数据驱动重传。 快速重传的工作方式是当收到三个相同的 ACK 报文时,会在定时器过期之前,重传丢失的报文段。
3. SACK 选择确认
如果要使用选择确认,建立 TCP 连接时,就要在 TCP 首部的选项中加上"允许 SACK"的选项,而双方必须都事先商定好。在 TCP 报文段的首部中增加 SACK 选项 ,以便报告收到的不连续的字节块的边界 。由于首部选项的长度最多只有 40 字节 ,而指明一个边界就要用掉 4 字节,因此在选项中最多只能指明 4 个字节块的边界信息。
4. Duplicate SACK
Duplicate SACK 又称 D-SACK,其主要使用了 SACK 来告诉发送方有哪些数据被重复接收。
使用D-SACK的优点:
- 可以让「发送方」知道,是发出去的包丢了,还是接收方回应的 ACK 包丢了;
- 可以知道是不是「发送方」的数据包被网络延迟了;
- 可以知道网络中是不是把「发送方」的数据包给复制了。