✍个人博客:Pandaconda-CSDN博客
📣专栏地址:http://t.csdnimg.cn/fYaBd
📚专栏简介:在这个专栏中,我将会分享 C++ 面试中常见的面试题给大家~
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪
64. TCP 四大拥塞控制算法是什么?
四大算法
拥塞控制主要是四个算法:1)慢启动,2)拥塞避免,3)拥塞发生,4)快速恢复。这四个算法不是一天都搞出来的,这个四算法的发展经历了很多时间,到今天都还在优化中。
一、慢热启动算法 -- Slow Start
所谓慢启动,也就是 TCP 连接刚建立,一点一点地提速,试探一下网络的承受能力,以免直接扰乱了网络通道的秩序。
慢启动算法:
- 连接建好的开始先初始化拥塞窗口 cwnd 大小为 1,表明可以传一个 MSS 大小的数据。
- 每当收到一个 ACK,cwnd 大小加一,呈线性上升。
- 每当过了一个往返延迟时间 RTT(Round-Trip Time),cwnd 大小直接翻倍,乘以 2,呈指数让升。
- 还有一个 ssthresh(slow start threshold),是一个上限,当 cwnd >= ssthresh 时,就会进入"拥塞避免算法"(后面会说这个算法)
二、拥塞避免算法 -- Congestion Avoidance
如同前边说的,当拥塞窗口大小 cwnd 大于等于慢启动阈值 ssthresh 后,就进入拥塞避免算法。算法如下:
- 收到一个 ACK,则 cwnd = cwnd + 1 / cwnd
- 每当过了一个往返延迟时间 RTT,cwnd 大小加一。
过了慢启动阈值后,拥塞避免算法可以避免窗口增长过快导致窗口拥塞,而是缓慢的增加调整到网络的最佳值。
三、拥塞发生状态时的算法
一般来说,TCP 拥塞控制默认认为网络丢包是由于网络拥塞导致的,所以一般的 TCP 拥塞控制算法以丢包为网络进入拥塞状态的信号。对于丢包有两种判定方式,一种是超时重传 RTO [Retransmission Timeout] 超时,另一个是收到三个重复确认 ACK。
超时重传是 TCP 协议保证数据可靠性的一个重要机制,其原理是在发送一个数据以后就开启一个计时器,在一定时间内如果没有得到发送数据报的 ACK 报文,那么就重新发送数据,直到发送成功为止。
但是如果发送端接收到 3 个以上的重复 ACK,TCP 就意识到数据发生丢失,需要重传。这个机制不需要等到重传定时器超时,所以叫做快速重传,而快速重传后没有使用慢启动算法,而是拥塞避免算法,所以这又叫做快速恢复算法。
超时重传 RTO [Retransmission Timeout] 超时,TCP 会重传数据包。TCP 认为这种情况比较糟糕,反应也比较强烈:
- 由于发生丢包,将慢启动阈值 ssthresh 设置为当前 cwnd 的一半,即 ssthresh = cwnd / 2
- cwnd 重置为 1
- 进入慢启动过程
最为早期的 TCP Tahoe 算法就只使用上述处理办法,但是由于一丢包就一切重来,导致 cwnd 又重置为 1,十分不利于网络数据的稳定传递。
所以,TCP Reno 算法进行了优化。当收到三个重复确认 ACK 时,TCP 开启快速重传 Fast Retransmit 算法,而不用等到 RTO 超时再进行重传:
- cwnd 大小缩小为当前的一半
- ssthresh 设置为缩小后的 cwnd 大小
- 然后进入快速恢复算法 Fast Recovery。
四、快速恢复算法 -- Fast Recovery
比如第 5 个包丢了,即使第 6、7 个包到达的接收端,接收端也一律返回第 4 个包的 ACK。当发送端收到 3 个重复的 ACK 时,意识到丢包了,于是马上进行重传,不用等到一个 RTO 的时间到了才重传。
这就是快速重传,它解决的是是否需要重传的问题。
TCP Tahoe 是早期的算法,所以没有快速恢复算法,而 Reno 算法有。在进入快速恢复之前,cwnd 和 ssthresh 已经被更改为原有 cwnd 的一半。快速恢复算法的逻辑如下:
- cwnd = cwnd + 3 MSS,加 3 MSS 的原因是因为收到 3 个重复的 ACK。
- 重传 DACKs 指定的数据包。
- 如果再收到 DACKs,那么 cwnd 大小增加一。
- 如果收到新的 ACK,表明重传的包成功了,那么退出快速恢复算法。将 cwnd 设置为 ssthresh,然后进入拥塞避免算法。
如图所示,第五个包发生了丢失,所以导致接收方接收到三次重复 ACK,也就是 ACK5。所以将 ssthresh 设置为当时 cwnd 的一半,也就是 6/2 = 3,cwnd 设置为 3 + 3 = 6。然后重传第五个包。当收到新的 ACK 时,也就是 ACK11,则退出快速恢复阶段,将 cwnd 重新设置为当前的 ssthresh,也就是 3,然后进入拥塞避免算法阶段。
65. 什么是滑动窗口?
滑动窗口是 TCP 协议中用于流量控制和可靠性传输的一种机制。它允许发送方和接收方之间动态地调整传输数据的速率。
滑动窗口的工作原理如下:发送方将要发送的数据分成一定大小的数据块,并为每个数据块分配一个序列号。接收方维护一个接收窗口大小的滑动窗口。
发送方将数据块按照序列号的顺序发送给接收方,并且等待接收方的确认。接收方接收到正确的数据块后,会发送一个确认报文给发送方,告知发送方已成功接收到该数据块。
发送方根据接收方发送回来的确认报文判断哪些数据块已成功发送,进而将滑动窗口向前滑动,并发送新的数据块。如果发送方收到一个确认报文超时或者收到一个冗余的确认报文,它将重新发送滑动窗口中的未确认数据。
滑动窗口的大小可以根据网络的拥塞情况和接收方的处理能力进行调整,这样可以保证数据的快速传输,并防止网络拥塞。另外,滑动窗口还可以通过选择性重传机制进行一些优化,只重传发生错误的数据块,提高传输效率。
总结一下,TCP 滑动窗口是一种用于流量控制和可靠性传输的机制,它通过动态调整数据的传输速率,保证数据的可靠性,并根据网络拥塞情况进行适应性调整。
66. 什么是糊涂窗口综合征?
糊涂窗口综合征(Silly Window Syndrome)是一种网络通信问题,它指的是在 TCP 协议中发送方发送数据速率过慢,导致接收方的接收窗口大小变得非常小,从而降低了网络的吞吐量。
具体而言,当发送方发送的数据块非常小(小于接收方的缓冲区大小的一半)且连续到达时,接收方的滑动窗口会变得非常小,因为接收方不能确认接收到的数据块之后还会有连续到达的数据。这意味着接收方需要频繁地发送窗口更新通知给发送方,造成了额外的网络开销。
这种情况下,网络的吞吐量会显著降低,因为发送方需要等待接收方的窗口更新才能发送更多的数据,而接收方发送窗口更新的频率较低。
为了避免糊涂窗口综合征,可以采用一些策略,如延迟发送窗口更新的通知,合并多个窗口更新为一个大的窗口更新,或者通过适当调整发送方的发送速率来避免过于频繁的窗口更新。
需要注意的是,糊涂窗口综合征在现代网络中较为少见,因为网络设备和操作系统通常会采取一些技术手段进行优化,例如使用延迟确认等。但了解和了解糊涂窗口综合征对于理解网络性能和 TCP 协议的工作原理仍然是有价值的。