TCP为什么可靠之“拥塞控制”

news2024/9/9 6:24:36

拥塞控制是对网络层面的控制,主要是为了避免发送方发送过多的数据导致网络阻塞,以及出现网络阻塞时能够调整数据发送速率,达到对网络阻塞的一个控制。

拥塞窗口

拥塞窗口cwnd,是发送方维护的一个状态变量,会根据网络的拥塞程度动态变化

发送窗口swnd和接收窗口rwdn是约等于的关系,有了拥塞窗口cwnd之后,发送窗口的值就等于min(cwnd,rwnd),也就是拥塞窗口和接收窗口的最小值

拥塞窗口cwnd的变化规则:

  • 只要网络中没有出现拥塞,cwnd就会增大

  • 一旦网络出现拥塞,cwnd就会减小

只要发送方没有在超时时间内接收到ACK应答报文,触发了超时重传,就会认为网络出现了拥塞。

对于网络拥塞的控制,主要通过几个算法实现:

慢启动

在刚建立完TCP连接之后,会有一个慢启动的过程,而不是一上来直接发送大量的数据。

慢启动期间,【当发送方每收到一个ACK确认报文,拥塞窗口就会加1,直到窗口的大小达到慢启动门限】。慢启动门限一般是65535字节。

所以在慢启动期间,窗口大小的增长呈指数增长

拥塞避免

当拥塞窗口大小达到慢启动门限后,就进入拥塞避免阶段,【此时发送方每收到一个ACK确认报文,拥塞窗口就增加窗口分之1的大小,也就是每收到窗口大小个ACK确认报文,窗口大小就加1】

拥塞避免阶段,窗口大小呈线性增长。

随着发送速率的增长,网络可能会出现阻塞,导致丢包,此时进入到拥塞发生阶段,这时候就需要重传数据

拥塞发生

重传数据主要有两种机制,一种是超时重传,另一种是快速重传和快速恢复

  • 超时重传

当发生了超时重传,就会使用拥塞发生算法:【慢启动门限会变为窗口大小的一般,拥塞窗口大小设为初始值,接着重新进入慢启动】

这种方式为了避免继续发送较多的数据而导致网络继续阻塞,而大大减少了数据的发送量

在linux系统中,我们可以使用命令来查看每一个tcp连接拥塞窗口的初始值,一般为10

ss -nli | grep cwnd

  • 快速重传

还有另一种重传算法,也就是快速重传:当接收方发现中间丢了某一个包时,就连续发送3次丢失包的前一个包的ACK报文,于是发送方连续3次接收到相同的ACK报文,就能快速重传丢失的包,不必等到超时再重传

此时,【拥塞窗口大小变为原来的一半,慢启动门限设置为新拥塞窗口的大小,之后进入快速恢复阶段】

  • 快速恢复

快速恢复算法如下:

  • 拥塞窗口cwnd = 慢启动门限 + 3(3的意思是确认有3个数据包被收到了)

  • 重传丢失的数据包

  • 如果再收到重复的ACK,则cwnd + 1

  • 如果收到新的ACK,则把cwnd设置为慢启动门限的值,之后进入拥塞避免阶段。(恢复过程结束,进入到恢复之前的状态)

快速重传和快速恢复算法一般同时使用

总结

TCP协议的拥塞控制主要通过几个算法实现的,包括慢启动,拥塞避免,超时重传,快速重传和快速恢复

  • 当TCP连接刚建立的时候,会进入【慢启动】阶段,也就是设置一个较小的拥塞窗口,发送方每收到一个ACK报文,拥塞窗口就加1,直到窗口大小达到慢启动门限

  • 达到慢启动门限后,就进入【拥塞避免】阶段,发送方每收到拥塞窗口大小个ACK报文,窗口大小就加1

  • 随着拥塞窗口大小,也就是发送速率的不断增加,网络可能会出现拥塞导致丢包,此时就需要重传数据,【重传】主要有两种机制

    • 一种是超时重传,此时慢启动门限会设置为拥塞窗口的一半,窗口大小恢复为初始值,接着重新进入慢启动,发送速率就会瞬间下降很多

    • 另一种是快速重传和快速恢复,当发送方连续接收到重复的ACK报文时,就认为发生丢包,此时拥塞窗口就会设置为原来的一般,慢启动门限设置为原来的一半,随后进入快速恢复阶段。快速恢复阶段会重传丢失的报文,当收到ACK后,拥塞窗口设置为慢启动门限,接着进入拥塞避免阶段。

这些拥塞控制算法能够防止一下子发送过多的数据导致网络拥塞,以及出现网络拥塞时及时调整数据的发送速率。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1312548.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue组件封装知识总结

一、为什么要封装组件 首先,一个好问题,面试要考的!为什么要封装组件呢? 提高代码的复用性:通过封装,可以将一段代码或一部分功能抽象为一个独立的组件,并在不同的项目或场景中重复使用。这样可…

simulinkveristand联合仿真——模型导入部署简单人机界面

目录 软件版本 simulink模型编译 veristand导入模型 veristand模型参数设置 veristand配置人机交互界面 veristand模型部署运行 软件版本 matlab2020a,veristand2020 R4 环境搭建及软件获取可看simulink&veristand&labview联合仿真环境搭建-CSDN博客…

记录 | docker报错could not select device driver ““ with capabilities: [[gpu]].

ubuntu18.04 上启动 docker start 报错: could not select device driver “” with capabilities: [[gpu]]. docker: Error response from daemon: could not select device driver “” with capabilities: [[gpu]]. ERRO[0005] error waiting for container: con…

如何做到人均告警减少 90%?B 站新一代告警平台的设计与实践

一分钟精华速览 B 站的业务规模和用户群体不断扩大,对于服务的稳定性和可用性的要求也日益增高。这就需要 B 站的监控告警系统能够及时、准确地发现和定位问题,以便尽快解决,维护好用户的使用体验。 本文是对 B 站在告警监控系统上的一次重…

MySQL如何进行Sql优化

(1)客户端发送一条查询语句到服务器; (2)服务器先查询缓存,如果命中缓存,则立即返回存储在缓存中的数据; (3)未命中缓存后,MySQL通过关键字将SQ…

网络层--TCP/UDP协议

目录 一、TCP/UDP协议介绍 1、UDP(User Datagram Protocol)--用户数据报协议 1.1 UDP报文格式 1.2 UDP协议的特性 2、TCP(Transmission Control Protocol )--传输控制协议 2.1 TCP报文格式 2.2 TCP协议的特性 2.3 TCP三次握手 2.4 四次挥手 三、TCP和UDP的区别 四、t…

关于“Python”的核心知识点整理大全21

9.3.2 Python 2.7 中的继承 在Python 2.7中,继承语法稍有不同,ElectricCar类的定义类似于下面这样: class Car(object):def __init__(self, make, model, year):--snip-- class ElectricCar(Car):def __init__(self, make, model, year):supe…

xcode 修改 target 中设备朝向崩溃

修改xcode的target中的设备朝向导致崩溃。 从日志上看好像没有什么特别的信息。 之后想了想,感觉这个应该还是跟xcode的配置有关系,不过改动的地方好像也只有plist。 就又翻腾了半天plist中的各种配置项,再把所有的用户权限提示相关的东西之…

运筹学经典问题(三):最大流问题

问题描述 给定一个图网络 G ( V , E ) G(V, E) G(V,E),网络中连边的权重代表最大容量,在这个图中找出从起点到终点流量最大的路径。 数学建模 集合: I I I:点的集合; E E E:边的集合。 常量&#x…

全光谱的灯对人体有什么伤害?考公护眼台灯推荐

什么是全光谱?全光谱是是一种能够模拟自然光谱的照明设备,通过发出包含所有可见光波长的光线,使人们感受到与自然光类似的照明效果。不同于传统的白炽灯或荧光灯,全光谱灯被认为能够提供更好的视觉质量和更健康的光学经验。现在市…

泊松分布、泊松定理

泊松分布 假设随机变量所有可能的取值为,并且取各个值的概率为: , 其中是常数 那么就称服从参数为的泊松分布,记为。 泊松定理 设是常数,是任意正整数,并且,那么对任意一个非负整数&am…

新一代“垫图”神器,IP-Adapter的完整应用解读

导读 不用训练lora,一张图就能实现风格迁移,还支持多图多特征提取,同时强大的拓展能力还可接入动态prompt矩阵、controlnet等等,这就是IP-Adapter,一种全新的“垫图”方式,让你的AIGC之旅更加高效轻松。 …

14个最经典的git命令,你知道吗?

1 学习14个Git命令,因为你将会在99%的时间里使用它们 必须了解的命令整理 1,git init 初始化一个新的Git仓库。 这将在当前目录中创建一个名为".git"的子目录,Git会将所有仓库的元数据存储在其中。 2,git clone 克…

使用Python绘制二元函数图像详解

概要 在数据科学、数学建模和机器学习中,经常需要可视化二元函数的图像以更好地理解函数的行为。Python提供了丰富的绘图库,如Matplotlib和NumPy,使得绘制二元函数图像变得简便而灵活。本文将介绍如何使用Python创建并美化二元函数图像&…

pandas读取Excel表指定数值 计算总和

题目要求:在一个文件夹里面有424个Excel表格,每个表格中都是统一的,如下图。要求计算所有表格中金额的总和。 上代码: import os import glob import pandas as pd# 指定文件夹路径 folder_path C:\\Users\\Administrator\\Desk…

Salesforce“卷土重来”:对中国CRM市场影响在哪?

于本土CRM而言,Salesforce是一面镜子,也更是催化剂。 长期来看,Salesforce的加入,从某种程度上将会加速中国CRM赛道的合理价值曲线的走向,通过带动外界对于CRM整个赛道的关注和热度,进而加速本土CRM的成长…

Java学习-连接Mysql数据库

1.先在Mysql里面构建一个表格 例子:名字为user1,两列分别为name、score 2.正确导入了MySQL的JDBC驱动程序 2.1 下载驱动包(与自己的服务器版本匹配) 官网地址:Maven Repository: mysql mysql-connector-java 8.0.29 …

JVM调优:参数(学习笔记)

一、jvm的运行参数 标准参数 -help、-version、-D参数 jvm的标准参数,一般都是很稳定的,在未来的JVM版本中不会改变,可以使用java -help 检索出所有的标准参数。 通过以下命令查看: 命令:java -help 可以看到我们经常…

C与C++编程语言的区别和联系

一、引言 C和C是两种广泛使用的编程语言,它们都在软件开发领域有着广泛的应用。虽然C是从C语言演化而来的,但两者之间存在一些重要的区别和联系。本文将详细介绍这两种编程语言的相同点和不同点,并通过实际例子进行说明。 二、C与C的相同点 …

如何查看Linux中glibc的Version

用ldd --version ldd --version 运行libc.so 你没有看错,libc.so是一个可执行程序。 但前提是你要找到它。因为它并不在PATH所包含的目录下。 ppdell:~$ ldd which cat | grep libclibc.so.6 > /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0e6fb34000)ppdell:~…