认识 TCP 协议(下)

创作不易,喜欢的话请点赞收藏转载,您的支持是我更新的最大动力!!!

本篇文章开始了解 TCP 协议的重传机制、流量控制和拥塞控制。关于 TCP 协议的基础、三次握手和四次挥手可以参考上一篇文章:认识 TCP 协议(上)

TCP 协议重传机制

当客户端和服务端进行网络通信时,在网络环境不良的情况下,会出现数据丢失。TCP 协议提供了多种重传机制来保证数据的可靠传输。

超时重传

超时重传,当发送方发送一个 TCP 报文段后,会启动一个定时器计时,如果在规定的时间内没有收到对应的确认 ACK 报文段,发送方会假设该报文段丢失,并重新发送该报文段。如下图所示:

在网络通信中,我们习惯用 RTT 来表示往返时间,指从发送方发送数据到接收方接收到相应数据,并将确认信息返回到发送方的整个往返时间。如下图所示:

超时重传是以 RTO 来表示的,即超时重传时间。一般情况下,超时重传时间 RTO 的值等于或略大于往返时间 RTT。如下图所示:

若超时重传时间 RTO 小于往返时间 RTT 时,会导致重发快,增加了网络拥塞,从而可能引发更多的通信数据丢失。如下图所示:

若超时重传时间 RTO 大于往返时间 RTT 时,会导致重发慢,效率低和性能差。如下图所示:

快速重传

快速重传,当发送方发送一个数据包(通常是 TCP 报文段)后,会启动一个定时器计时,然后继续发送报文。但如果发送方连续收到三个相同的确认 ACK 报文段,表示接收方已经接收到后续的报文段,但某个中间的报文段丢失了。发送方不等待定时器超时,而是立即重传丢失的报文段,以提高传输效率。如下图所示:

SACK 重传

当超时重传和快速重传发生的时候,客户端不知道重传丢失的那个报文还是重传后面的所有报文。SACK 重传,当接收方收到报文后,会发送一个确认 ACK 报文段,其中包含 SACK 选项字段。SACK 选项字段会指示接收方已经正确接收到的报文段范围,即连续收到的报文段以及中间缺失的部分。发送方根据接收到的 SACK 选项字段,可以知道哪些报文段已经到达,哪些报文段还未到达。发送方可以选择性地重传丢失的报文段,只重传未到达的部分,而无需重传已经接收到的报文段。

通过 SACK 重传,TCP 协议可以更加高效地处理乱序报文段,减少不必要的重传和带宽浪费。它可以帮助提高数据传输的效率和可靠性,并减少网络拥塞的影响。

需要注意的是,SACK 重传是可选的,不是所有的 TCP 实现都支持该机制。另外,SACK 重传的使用需要接收方和发送方都支持并正确处理 SACK 选项字段。

Duplicate SACK 重传

Duplicate SACK 重传和 SACK 重传是差不多,只不过 Duplicate SACK 重传可以在 ACK 报文丢失的情况下,确定哪些数据被重复接收了。

接收方收到重复的报文段后,会在确认 ACK 报文段的 SACK 选项中包含重复的 SACK 选项字段。SACK 选项字段指示重复报文段的范围,使发送方能够识别并了解哪些报文段是重复接收的。1发送方接收到带有 D-SACK 选项的确认 ACK 报文段后,可以根据其中的信息来确定是否需要采取相应的措施,例如调整拥塞窗口大小、重传被错误地丢弃的报文段等。

D-SACK 机制有助于发送方更好地了解网络中发生的重复接收情况,并根据这些信息进行相应的处理。它可以提高 TCP 协议的可靠性和性能,并减少不必要的重传。

需要注意的是,D-SACK 机制是可选的,并不是所有的 TCP 实现都支持该机制。此外,D-SACK 机制的使用需要接收方和发送方都支持并正确处理 D-SACK 选项字段。

滑动窗口

滑动窗口(Sliding Window)是 TCP 协议中用于流量控制和拥塞控制的一种机制。它允许发送方在不等待确认的情况下连续发送多个报文段,以提高传输效率。

在 TCP 通信中,发送方和接收方之间有一个滑动窗口的概念。滑动窗口定义了发送方可以连续发送的报文段数量,而接收方则通过确认报文段的方式告知发送方窗口中还有多少可用的空间。发送方根据接收方提供的窗口大小来决定发送的报文段数量,并随着确认的到达逐渐滑动窗口,发送新的报文段。窗口大小实际是由操作系统开辟的缓存空间。

当客户端和发送端建立连接后,双方会协商好窗口大小,然后客户端会不断向服务端发送数据,窗口变化如下图所示:

客户端在发送报文的时候会不断的消耗窗口,当把窗口中的数据发送完后,可用窗口就会为0,如下图所示:

服务端在接收数据的时候,也会维护一个窗口,接收窗口大小约等于发送窗口大小。如下图所示:

客户端收到服务端对 32~36 字节确认的 ACK 报文,若窗口大小没有变化,则向右滑动 5 个字节,不断重复这个过程直至数据传输完毕。如下图所示:

通过滑动窗口机制,TCP 可以根据网络状况动态调整发送速率,以适应不同的网络延迟和带宽情况。它可以实现流量控制,确保发送方不会以过快的速度发送报文段,导致接收方无法处理。同时,滑动窗口也可以用于拥塞控制,根据接收方提供的窗口大小来控制发送方的发送速率,以避免网络拥塞。

流量控制

流量控制,是 TCP 协议本身的一种机制,用于防止发送方发送数据的速率过快,接收方来不及处理,从而避免数据丢失或丢包。

具体来说,当接收方处理数据的速度比发送方发送数据速度快时,流量控制机制可以限制发送方发送数据的速率,避免接收方来不及处理。这可以通过在 TCP 报文中添加一些控制字段来实现,例如滑动窗口机制中的窗口大小和接收方反馈的接收窗口通知等。

流量控制机制可以避免发送方发送的数据量过大,导致接收方处理不过来,从而减少数据丢失或丢包的风险。同时,它还可以减轻接收方的负担,避免接收方因处理数据过载而崩溃。

拥塞控制

TCP 协议的拥塞控制也是一种机制,用于在数据传输过程中,当网络拥塞情况发生时,对发送方的发送速率进行调节,以减少数据包丢失,并恢复网络性能。

具体来说,当网络发生拥堵时继续发送大量数据,会导致数据丢失或丢包时,从而触发重传机制。重传机制又会反向增加网络负担,从而导致更多数据丢失或丢包,进入了一个恶性循环。TCP 协议的拥塞控制机制,可以通过慢启动算法、拥塞避免算法、调整 TCP 报文的拥塞窗口大小、快恢复算法来调节发送方的发送速率,以降低数据包丢失的风险。

慢启动算法

慢启动算法是一种用于提高网络拥塞避免和拥塞恢复机制的方法,它主要应用于TCP 协议中。在慢启动算法中,发送方会逐渐增加其发送的数据量,而不是一开始就发送大量的数据。其规则主要是发送方每收到一个 ACK 报文时,拥塞窗口 cwnd 的大小会翻倍。如下图所示:

可以看出,慢启动算法的发包数会呈指数式增长。一般情况下,发送方会设置一个慢启动门限 ssthresh。当拥塞窗口 cwnd <= 拥塞避免阈值 ssthresh,则使用慢启动算法;当拥塞窗口 cwnd > 拥塞避免阈值 ssthresh 时,开始进入拥塞避免算法。

拥塞避免算法

TCP 拥塞避免算法是为了在网络拥塞的情况下控制数据传输速率的一种机制。一旦拥塞窗口 cwnd 大小达到拥塞避免阈值 ssthresh,TCP发送方就会进入拥塞避免阶段。在这个阶段,拥塞窗口以线性增加的速度增长,而不是指数级增长。每次收到一个确认,拥塞窗口增加的大小也减小。

快速恢复

TCP快速恢复算法是TCP拥塞控制机制中的一部分,用于在网络拥塞时快速恢复数据传输速率。它是TCP拥塞避免算法的一个扩展,旨在减少由于发生拥塞而导致的传输延迟。在快速恢复阶段,TCP发送方不再按照慢启动或拥塞避免的方式线性增加拥塞窗口,而是每收到一个重复确认,拥塞窗口增加1个MSS(最大报文段长度)。

总结

本篇我们先是介绍 TCP 协议的重传机制,主要有超时重传、快速重传、SACK 重传和 D-SACK 重传,且分别介绍了它们的特点。接着又着重介绍了 TCP 协议中的滑动窗口机制,通过几张图简洁明了地描述了发送方和接收方在传输数据过程中窗口的变化过程。此外,我们也简单的了解了流控控制在 TCP 传输协议的重要性。最终,我们系统性地学习了 TCP 协议的拥塞控制,主要有慢启动、拥塞避免和快回复。

相关推荐
奶球不是球2 分钟前
el-table(elementui)表格合计行使用以及滚动条默认样式修改
前端·vue.js·elementui
liuyang___4 分钟前
vue管理布局左侧菜单栏NavMenu
前端·javascript·vue.js
@业精于勤荒于嬉13 分钟前
将图片存储至阿里云 OSS
前端·阿里云·云计算·oss
冲鸭ONE38 分钟前
for循环优化方式有哪些?
后端·性能优化
打野赵怀真38 分钟前
render函数中return如果没有使用()会有什么问题?
前端·javascript
兮动人39 分钟前
DBeaver连接OceanBase数据库
后端
Riesenzahn40 分钟前
写一个左中右的满屏布局,左右固定220px,中间自适应并且要优先加载
前端·javascript
Riesenzahn40 分钟前
css在页面上画一个正方形,边长为页面宽度的一半
前端·javascript
tommyrunner42 分钟前
Cursor rule文件测试 一秒了解AI行为规则文件
前端·cursor
北京_宏哥1 小时前
《手把手教你》系列基础篇(九十三)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-上篇(详解教程)
java·前端·selenium