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

在传输数据时,网络中会出现的问题

丢包 - 问题的根源

核心思想:TCP通过"确认"机制来感知丢包。

假设
发送方要发送3个数据包:P1, P2, P3。

情况A:正常传输(无丢包)

发送方                         接收方|-------- P1 (seq=1) ------->|  发送P1,启动P1的定时器|<------- ACK for 2 ---------|  收到P1,回复ACK:"下一个我期望seq=2"|-------- P2 (seq=2) ------->|  P1确认收到,停止其定时器;发送P2,启动P2定时器|<------- ACK for 3 ---------|  收到P2,回复ACK:"下一个我期望seq=3"|-------- P3 (seq=3) ------->|  P2确认收到;发送P3...|<------- ACK for 4 ---------|  ...如此继续

(注:ACK号是"期望的下一个序列号",所以ACK for 2 表示seq=1的数据已收到)

情况B:发生丢包(数据包丢失)

发送方                         接收方|-------- P1 (seq=1) ------->| |<------- ACK for 2 ---------|  P1成功送达|-------- P2 (seq=2) ------->|  ** P2在网络中丢失 **|-------- P3 (seq=3) ------->|  发送方不知道P2丢了,继续发P3|<------- ACK for 2 ---------|  接收方发现收到了seq=3,但没收到seq=2!它重复发送"ACK for 2",提醒发送方:"我还在等seq=2!"| (等待... 定时器超时...)    ||-------- P2 (seq=2) ------->|  ** 超时重传 ** P2|<------- ACK for 4 ---------|  一旦收到P2,接收方发现1,2,3都齐了,直接回复ACK for 4

情况C:发生丢包(ACK确认包丢失)

发送方                         接收方|-------- P1 (seq=1) ------->||         (ACK for 2 丢失)   X   P1的ACK丢了!|-------- P2 (seq=2) ------->|  发送方不知道ACK丢了,继续发P2|<------- ACK for 3 ---------|  接收方回复:"我收到了1和2,期望下一个是3"

关键点ACK是累积确认的。当发送方收到ACK for 3时,它就知道不仅P2被成功接收,P1也一定被成功接收了(因为接收方是按顺序确认的),尽管它没收到P1的ACK。因此,P1的定时器此时会被停止,P1不会被重传。

超时重传 - 解决丢包的核心武器

超时重传的核心挑战在于:超时时间设为多久?

  • RTT与RTO
    • RTT:一个数据包从发送到收到其ACK的往返时间

    • RTO超时重传时间。TCP的RTO是根据网络状况动态计算的,而不是一个固定值。

工作原理(简化版)

  • 持续测量:TCP对每个成功传输的包(非重传的)测量其RTT。

  • 平滑计算:使用一个公式来平滑RTT的波动,计算出SRTT。
    SRTT = (α * SRTT) + ((1 - α) * RTT_sample)
    (α是一个平滑因子,如0.875)

  • 设置RTO:RTO = SRTT + 4 * DevRTT (DevRTT是RTT的偏差,代表波动程度)

这个机制使得RTO能自适应网络:网络快时RTO变小,反应灵敏;网络拥堵延迟大时,RTO变大,避免不必要的重传。

包重复 - 重传机制的副作用

原因:几乎总是由"不必要的"超时重传引起。

发送方                         接收方|-------- P1 (seq=1) ------->|  P1正常发送(P1的ACK因网络延迟未到达)|--[Timeout]-- P1 (seq=1) -->|  ** 重传P1 **|<------- ACK for 2 ---------|  收到第一个P1或重传的P1,回复ACK|-------- P2 (seq=2) ------->||... (延迟的原始P1到达) ...>|  ** 重复的P1到达!**

接收方收到了两个seq=1的包。

TCP的解决方案:序列号
接收方维护着一个RCV.NXT变量,表示期望收到的下一个序列号。

  • 当收到seq=1的包时,它处理这个包,并将RCV.NXT更新为2。

  • 当又一个seq=1的包到达时,接收方发现seq=1 < RCV.NXT=2,立刻知道这是一个旧的、重复的包,于是直接丢弃。

但这里有个关键细节:接收方在丢弃重复包后,必须再次发送一个ACK for 2。为什么?
因为发送方可能没有收到第一次的ACK for 2(这正是它重传的原因)。这次重复的ACK确保了发送方最终能知道P1已成功接收,从而停止重传定时器并前进。

乱序 - 网络路径不一致的后果

原因:数据包通过网络的不同路径,导致后发先至。

发送方                         接收方|-------- P1 (seq=1) ------->||-------- P2 (seq=2) ------->| ** P2走了一条慢路径 **|-------- P3 (seq=3) ------->| |<------- ACK for 2 ---------| 收到P1,期望P2|<------- ACK for 2 ---------| 收到P3!但P2还没到。这是乱序。接收方仍然回复"ACK for 2",催促P2。|-------- P4 (seq=4) ------->| 发送方继续发送,但被接收方缓冲...|<------- ACK for 2 ---------| 再次收到重复ACK|-------- P2 (seq=2) ------->| ** 延迟的P2终于到达 **|<------- ACK for 5 ---------| 接收方现在一下子收到了P2, P3, P4!它一次性确认所有数据,回复"ACK for 5"

TCP的解决方案:序列号 + 接收缓冲区 + 累积确认

  • 接收缓冲区:当接收方收到P3 (seq=3)时,它发现seq=3不是期望的seq=2。但它不会丢弃P3,而是将其存入接收缓冲区

  • 继续发送重复ACK:它仍然回复ACK for 2,告诉发送方:“我还在等seq=2,别的数据我先帮你存着”。

  • 填补空缺:当缺失的P2 (seq=2)最终到达时,接收方发现序列号2, 3, 4在缓冲区中已经形成一个连续的数据块。

  • 累积确认:接收方此时不会为P2、P3、P4单独发送ACK,而是一次性发送一个ACK for 5,告诉发送方:“5之前的所有字节我都收到了”。这大大减少了ACK的数量,提高了效率。

快速重传:基于乱序的优化
乱序触发的"重复ACK"被TCP作为一个网络可能发生丢包的早期信号

快速重传算法:当发送方连续收到3个重复的ACK(即总共4个相同的ACK)时,它强烈地暗示这个数据包很可能已经丢失(而不是仅仅延迟)。此时,发送方不再等待超时,而是立即重传被认为丢失的数据包。

发送方                         接收方|-------- P1 (seq=1) ------->||<------- ACK for 2 ---------||-------- P2 (seq=2) ------->| ** 丢失 **|-------- P3 (seq=3) ------->||<------- ACK for 2 ---------| Dup ACK #1 (收到P3,但缺P2)|-------- P4 (seq=4) ------->||<------- ACK for 2 ---------| Dup ACK #2 (收到P4,但缺P2)|-------- P5 (seq=5) ------->||<------- ACK for 2 ---------| Dup ACK #3 (收到P5,但缺P2)|*** 快速重传!不等待超时 ***||-------- P2 (seq=2) ------->| ** 立即重传P2 **|<------- ACK for 6 ---------| 收到P2,P3,P4,P5都连续了,累积确认到6

小结

问题触发条件TCP的解决机制关键数据结构/概念
丢包ACK超时或收到3个重复ACK超时重传 / 快速重传重传定时器、RTO、重复ACK计数
超时重传数据包或ACK丢失自适应RTO算法平滑RTT、RTT偏差
包重复不必要的重传序列号 + 丢弃 + 再确认序列号空间、接收窗口下沿
乱序数据包非顺序到达序列号 + 接收缓冲区 + 累积确认接收缓冲区、滑动窗口、累积ACK
http://www.dtcms.com/a/481851.html

相关文章:

  • jenkins在使用中遇到的问题
  • 第8章 zynq uboot更新系统镜像并引导启动和个人心得
  • 网站系统升级建设合同汽车之家官网首页网页
  • 电销外包公司有哪些seo学习网站
  • 基于弱监督病灶增强的模型展开式快速磁共振成像|文献速递-文献分享
  • 十四、OpenCV中的形态学操作
  • 算法279. 完全平方数
  • Prometheus pushgateway学习
  • MySQL索引结构:B树与B+树
  • 进程的基本认识
  • Webpack 打包优化与骨架屏结合:双管齐下提升前端性能与用户体验
  • 鸿蒙:在沙箱目录下压缩或解压文件
  • 智能SQL客户端Chat2DB技术解析
  • 电影网站推广什么是网络营销的主要职能之一
  • Transformers库用法示例:解锁预训练模型的强大能力
  • 大气污染扩散calpuff模型:数据预处理、Calmet气象模块、Post Tools 后处理工具及绘图工具
  • 用气安全与能效优化平台
  • 02117 信息组织【第三章】
  • 自己建设淘宝客网站需要备案么wordpress插件 投票
  • Wireshark 4.4.9 设置为中文界面方法
  • 极限AI Coding,腾讯云“黑客松”大赛回顾(内有作品开源)
  • 【工具分享】Dota游戏平台助手
  • 网站制作找云优化口碑好的网站定制公司
  • 精品建站公司2345网址大全下载到桌面
  • HENGSHI SENSE异构过滤架构:基于三层执行引擎的跨源联邦查询性能优化实践
  • 语言模型监督式微调(SFT)概述
  • 又开始了 小程序定制
  • 前端面试-箭头函数
  • 翻译类公司网站模板node做网站后台
  • 2018做网站哪里可以做寄生虫网站