当前位置: 首页 > news >正文

TCP的拥塞控制

TCP(传输控制协议)是互联网中保证数据可靠传输的核心协议,而拥塞控制是 TCP 的 “智能交通管理系统”—— 当网络出现拥堵时,它能避免数据 “堵车”,防止网络瘫痪。

一、为什么需要拥塞控制?(通俗理解)

想象你开车从 A 到 B,路上车太多就会堵车。网络中,“车” 就是数据,“道路” 就是网线 / 无线信号。如果发送方不管不顾地发数据,网络设备(路由器、交换机)的缓冲区会被塞满,导致数据丢失、延迟飙升,就像高速路彻底堵死。

拥塞控制的作用:让发送方根据网络 “路况” 动态调整发送速度,既不浪费带宽,又不造成拥堵。

二、拥塞控制的核心原理

TCP 通过拥塞窗口(cwnd) 控制发送速度:

  • 拥塞窗口是发送方在未收到确认前,最多能发送的数据量(单位:字节或报文段)。
  • 网络越通畅,cwnd 越大(发送越快);网络拥堵时,cwnd 减小(发送变慢)。

发送方实际发送速度还受接收窗口(rwnd) 限制(接收方告诉发送方 “我还能接多少”),最终发送窗口取 cwnd 和 rwnd 的最小值。

三、拥塞控制的四个阶段

TCP(以经典的 Reno 版本为例)通过四个阶段动态调整 cwnd:

  1. 慢启动(Slow Start)

    • 通俗:刚上高速,慢慢加速,测试路况。
    • 专业:初始 cwnd 很小(如 1~2 个报文段),每收到一个确认(ACK),cwnd 就翻倍(指数增长)。
    • 限制:当 cwnd 达到 “慢启动阈值(ssthresh)” 时,进入下一阶段。
  2. 拥塞避免(Congestion Avoidance)

    • 通俗:接近限速,平稳行驶,不再猛加速。
    • 专业:cwnd 不再翻倍,而是每收到一轮 ACK(即一个往返时间 RTT)增加 1 个报文段(线性增长)。
    • 目的:避免因过快发送导致拥堵。
  3. 拥塞发生(Congestion Detection)

    • 通俗:发现前方堵车(比如收到 “数据丢失” 的信号),立刻减速。
    • 专业:当检测到丢包(如超时未收到 ACK,或收到 3 个重复 ACK),触发拥塞处理:
      • 若因超时丢包:ssthresh 设为当前 cwnd 的一半,cwnd 重置为 1,重新进入慢启动。
      • 若收到 3 个重复 ACK(表示数据可能只是轻微拥堵,未完全丢失):ssthresh 设为当前 cwnd 的一半,cwnd 设为 ssthresh,直接进入拥塞避免(快速恢复)。
  4. 快速恢复(Fast Recovery)

    • 通俗:堵车缓解后,慢慢恢复速度,不用从零开始。
    • 专业:仅在收到 3 个重复 ACK 时触发,cwnd 从 ssthresh 开始线性增长,减少重新慢启动的时间浪费。
四、如何检测网络拥堵?
  • 超时重传:发送方迟迟没收到 ACK,认为数据丢失(严重拥堵)。
  • 重复 ACK:接收方收到乱序数据时,会重复发送已收到的最后一个报文段的 ACK,发送方收到 3 个重复 ACK 后,判断为轻微拥堵(数据可能只是延迟,未丢失)。
五、举个例子

假设初始 ssthresh=16,cwnd=1:

  • 慢启动:cwnd 从 1→2→4→8→16(达到 ssthresh,进入拥塞避免)。
  • 拥塞避免:cwnd 从 16→17→18→…(每 RTT+1)。
  • 若此时检测到丢包:
    • ssthresh 设为当前 cwnd 的一半(如 18→9)。
    • 若为 3 个重复 ACK:cwnd=9,直接进入拥塞避免(9→10→11…)。
    • 若为超时:cwnd 重置为 1,重新慢启动(1→2→4→… 直到 9,再进入拥塞避免)。
六、为什么需要这么复杂?

网络状态是动态变化的(比如高峰期拥堵、闲时通畅),拥塞控制通过 “试探 - 调整 - 反馈” 的循环,在 “高效利用带宽” 和 “避免拥堵” 之间找平衡。没有它,网络可能频繁瘫痪,就像没有红绿灯和限速的马路会彻底堵死。

http://www.xdnf.cn/news/1251469.html

相关文章:

  • CSS :is () 与 :where ():简化复杂选择器的 “语法糖”
  • NodeJs学习日志(1):windows安装使用node.js 安装express,suquelize,sqlite,nodemon
  • 基于Hadoop的股票大数据分析可视化及多模型的股票预测研究与实现
  • 笔试——Day30
  • 如何快速掌握大数据技术?大四学生用Spark和Python构建直肠癌数据分析与可视化系统
  • 【数据结构与算法-Day 12】深入浅出栈:从“后进先出”原理到数组与链表双实现
  • 开疆智能ModbusTCP转Profinet网关连接EPSON机器人配置案例
  • Gitlab+Jenkins+K8S+Registry 建立 CI/CD 流水线
  • MATLAB深度学习之数据集-数据库构建方法详解
  • 无人机开发分享——基于行为树的无人机集群机载自主决策算法框架搭建及开发
  • 2025国赛数学建模C题详细思路模型代码获取,备战国赛算法解析——决策树
  • 信息安全概述
  • Dart中回调函数的简单实现
  • NY112NY117美光固态闪存NY119NY123
  • C++之vector类的代码及其逻辑详解 (下)
  • 【Excel】通过Index函数向下拖动单元格并【重复引用/循环引用】数据源
  • 【Linux】调试器gdb/cgdb的使用
  • 推荐一款优质的开源博客与内容管理系统
  • Android PDFBox 的使用指南
  • 【数据结构与算法】刷题篇——环形链表的约瑟夫问题
  • 8.6笔记
  • 93、【OS】【Nuttx】【构建】cmake menuconfig 目标
  • vxe-table表格编辑单元格,进行正则验证,不符合验证,清空单元格数据。
  • 【“连亏十年” 川机器人,启动科创板IPO辅导】
  • 短剧小程序系统开发:技术驱动下的内容创新之路
  • 后端服务oom
  • [linux] Linux系统中断机制详解及用户空间中断使用方法
  • Java技术栈/面试题合集(19)-架构设计篇
  • Android—服务+通知=>前台服务
  • 简单spring boot项目,之前练习的,现在好像没有达到效果