参考资料 :小林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协议保证数据传输可靠性的方法主要有:校验和、序列号、确认应答、超时重传、连接管理、流量控制、拥塞控制。
1. 数据校验:TCP报文头有校验和,采用CRC校验全部数据;
2. 序列号和确认应答:TCP通过给每个发送的数据段分配一个序号,以及使用确认机制ACK来跟踪数据的传输与接收。接收方会确认已经成功接收的数据,发送方则根据收到的确认确定哪些数据已经被成功传输,哪些需要重新发送。
3. 超时和重传:TCP使用超时机制来检测是否发生数据包丢失,如果发送方在一定时间内未收到确认,就认为数据包丢失,并触发响应的重传。这确保及时某个数据包在传输过程中丢失,最终仍能够被成功传递。
4. 连接管理:通信前确认通信实体的存在。(具体见【面试八股总结】传输控制协议TCP(一)-CSDN博客)
5. 流量控制:TCP使用滑动窗口机制进行流量控制,确保发送方不会以高于接收方处理速度的速率发送数据,这有助于防止接收方缓冲溢出,提高整个通信链路效率,防止数据包丢失。(具体见【面试八股总结】传输控制协议TCP(二)-CSDN博客)
6. 拥塞控制: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 包丢了;
- 可以知道是不是「发送方」的数据包被网络延迟了;
- 可以知道网络中是不是把「发送方」的数据包给复制了。