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

【计算机网络 - 基础问题】每日 3 题(二十二)

✍个人博客:Pandaconda-CSDN博客
📣专栏地址:http://t.csdnimg.cn/fYaBd
📚专栏简介:在这个专栏中,我将会分享 C++ 面试中常见的面试题给大家~
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪
📝推荐参考地址:https://www.xiaolincoding.com/(这个大佬的专栏非常有用!)

64. TCP 四大拥塞控制算法是什么?

四大算法

拥塞控制主要是四个算法:1)慢启动,2)拥塞避免,3)拥塞发生,4)快速恢复。这四个算法不是一天都搞出来的,这个四算法的发展经历了很多时间,到今天都还在优化中。

在这里插入图片描述

一、慢热启动算法 – Slow Start

所谓慢启动,也就是 TCP 连接刚建立,一点一点地提速,试探一下网络的承受能力,以免直接扰乱了网络通道的秩序。

慢启动算法:

  1. 连接建好的开始先初始化拥塞窗口 cwnd 大小为 1,表明可以传一个 MSS 大小的数据。
  2. 每当收到一个 ACK,cwnd 大小加一,呈线性上升。
  3. 每当过了一个往返延迟时间 RTT(Round-Trip Time),cwnd 大小直接翻倍,乘以 2,呈指数让升。
  4. 还有一个 ssthresh(slow start threshold),是一个上限,当 cwnd >= ssthresh 时,就会进入“拥塞避免算法”(后面会说这个算法)

二、拥塞避免算法 – Congestion Avoidance

如同前边说的,当拥塞窗口大小 cwnd 大于等于慢启动阈值 ssthresh 后,就进入拥塞避免算法。算法如下:

  1. 收到一个 ACK,则 cwnd = cwnd + 1 / cwnd
  2. 每当过了一个往返延迟时间 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 协议的工作原理仍然是有价值的。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • GP2D12红外距离传感器
  • MiniCPM3-4B | 笔记本电脑运行端侧大模型OpenBMB/MiniCPM3-4B-GPTQ-Int4量化版 | PyCharm环境
  • 分库分表-分页排序查询
  • Android开发高频面试题之——Android篇
  • 0-Mapbox简介及产品类型
  • Springboot Mybatis条件查询
  • 计算机网络 --- Socket 编程
  • 24.9.23学习笔记
  • 打造以太坊数据监控利器:InfluxDB与Grafana构建Geth可视化分析平台
  • 设计模式之中介者
  • pyqt QGraphicsView 以鼠标为中心进行缩放
  • LTE协议栈学习
  • [创业之路-151] :职能部门/非经营部门 VS 业务部门/经营部门划分与职责
  • 为什么推荐使用英文版LabVIEW
  • 论文阅读:Omni-Kernel Network for Image Restoration
  • 【css3】浏览器内核及其兼容性
  • bootstrap创建登录注册页面
  • CentOS从零开始部署Nodejs项目
  • flask接收请求并推入栈
  • GitUp, 你不可错过的秀外慧中的git工具
  • iOS | NSProxy
  • Js基础——数据类型之Null和Undefined
  • LeetCode18.四数之和 JavaScript
  • Making An Indicator With Pure CSS
  • Promise初体验
  • PyCharm搭建GO开发环境(GO语言学习第1课)
  • ReactNativeweexDeviceOne对比
  • Sass Day-01
  • SQLServer之创建数据库快照
  • weex踩坑之旅第一弹 ~ 搭建具有入口文件的weex脚手架
  • 简单数学运算程序(不定期更新)
  • 世界上最简单的无等待算法(getAndIncrement)
  • 微信如何实现自动跳转到用其他浏览器打开指定页面下载APP
  • 延迟脚本的方式
  • 一、python与pycharm的安装
  • 用 Swift 编写面向协议的视图
  • 用简单代码看卷积组块发展
  • 运行时添加log4j2的appender
  • ​Spring Boot 分片上传文件
  • ​软考-高级-系统架构设计师教程(清华第2版)【第9章 软件可靠性基础知识(P320~344)-思维导图】​
  • # 数据结构
  • $分析了六十多年间100万字的政府工作报告,我看到了这样的变迁
  • (6)【Python/机器学习/深度学习】Machine-Learning模型与算法应用—使用Adaboost建模及工作环境下的数据分析整理
  • (el-Transfer)操作(不使用 ts):Element-plus 中 Select 组件动态设置 options 值需求的解决过程
  • (react踩过的坑)Antd Select(设置了labelInValue)在FormItem中initialValue的问题
  • (附源码)spring boot球鞋文化交流论坛 毕业设计 141436
  • (九十四)函数和二维数组
  • (蓝桥杯每日一题)平方末尾及补充(常用的字符串函数功能)
  • (五)c52学习之旅-静态数码管
  • (源码版)2024美国大学生数学建模E题财产保险的可持续模型详解思路+具体代码季节性时序预测SARIMA天气预测建模
  • (转)Android学习笔记 --- android任务栈和启动模式
  • .env.development、.env.production、.env.staging
  • .Mobi域名介绍
  • .Net Core 微服务之Consul(三)-KV存储分布式锁
  • .net反编译的九款神器