TCP滑动窗口协议与流量控制

news2025/1/17 21:46:20

        谈到TCP的滑动窗口协议与流量控制,便会想起2006年去华为-3COM(现H3C公司时)面试时的场景。

        当年毕业后,刚刚学了一点TCP的皮毛,仅仅是知道了TCP是面向连接的协议,以对每个报文都进行确认+超时重传的机制来保证端到端的可靠传输;并在面试前背了一下TCP协议头部的数据结构后,便信心满满的自以为已经掌握TCP的所有精髓成为一个不折不扣的TCP专家了。

        结果面试时领导只问了我二个问题:1,和我讲讲TCP滑动窗口协议与流量控制的过程。2,请详细描述一下TCP慢启动的原理。这二个问题当场就把我打回了原形。虽然最终,领导也许看我那时年纪尚小还有进步空间(骨骼清奇,是一个练武的奇才)最终还是给我发了offer,但这二个问题一直记我记忆尤新。

        时光飞逝,自己人到中年,自己也成了带团队的所谓领导了。10多年来,面人无数,面试时也一直用这二个问题来考查应聘者对TCP的理解程度以及面试着对技术的刨根问底的精神,实际上这么多年也几乎没有碰到过能真正讲清楚这二个问题的应聘者,能讲一些大面上的基本原理的应聘者已经算是佼佼者了。最近新的实验室时老碰到网络的连接问题,所以花了点时间给部门里的同事准备了一系列TCP/IP相关的培训。事后有同事向我反馈:TCP滑动窗口协议与流量控制,TCP慢启动这二块不是很好理解,问我能不能写做个简单的汇总,写成文章以备后续查阅,所以就有了此文。

       本文假设,读者有TCP的基本常识,理解并掌握了:IP协议,TCP是面向连接的可靠传输协议,TCP重传机制,网络延时RTT,网络延时抖动,网络丢包率,网络带宽。

一,什么是TCP的流量控制

        大家都已经知道 TCP是面向连接的可靠的传输协议,顾明思义,TCP协议能保证每人数据包被正确的从发送方传送到接收方,它所依赖的最重要的手段就是就是重传与确认应答机制,但如果只依赖于重传和确认应答机制,在某些场景(或者说大部分)下是会出错的,我们还需要流量控制,来保证发送方和接收方之间的数据流发送速度才可以让TCP稳定运行,这就是控制发送方和接收方之间的数据流发送速度就是流量控制。

二,什么场景下要做流量控制

        考虑到发送方和接收方的能力不同,有以下三个场景:

1,发送方发送得慢,接收方接收得快----------------------------不需要流量控制

2,发送方的发送速度和接收方的接收速度一样快-------------不需要流量控制

3,发送方发送得快,接收方接收得慢----------------------------需要流量控制

所以只有第3个场景需要做流量控制,让我们来考虑一下:

        如果发送者发送数据过快,接收者来不及接收,那么当接收方的缓冲区满了之后,就会有分组报文丢失。

        分组报文丢失后,接收方就不会发送确认报文回给发送方,那么进一步就会引发发送方的重发,发送方重发的报文越多,则接收方更来不及处理,丢失的报文就会越多,丢失的报文越多,则又会引发发送方发送更多的重发报文......

        由此恶性循环,最终导致网络状态持续恶化直到TCP连接断开或者网络崩溃。那么为了避免分组丢失及网络的持续恶化,我们在这样的情况下需要对发送方的发送速度进行控制,使得接收者来得及接收,这就是流量控制

       流量控制根本目的是防止分组丢失,避免不必要的报文重发,它是构成TCP可靠性的非常重要的一方面。

三,如何实现流量控制

       为了实现流量控制,TCP协议引入了滑动窗口协议(连续ARQ协议)。滑动窗口协议既保证了分组无差错、有序接收,也实现了流量控制。一句话总结起来非常简单:接收方返回的 ACK 中会包含自己的接收窗口的大小,并且发送发检查这个窗口的大小,用来控制自己的数据发送速度。

四,流量控制的具体原理

       首先我们来看一下,TCP应答机制下,如何来保证数据的传输的可靠性,既如何保证报文被发发送方正确的发送到接收方。

A,引入停止等待协议和重传机制,来保证传输的可靠性

数据发送方在发送下一个数据块之前需要等待接收对已发送数据的确认,如下图所示:

        这种协议的优点在于每个报文都能得到及时的反馈,一般只用于需要即时响应并对分组的发送顺序有严格的顺序要求的协议。

        这种方法存在最大的问题在于,网络利用率极低,以上图为例,假设按照主机A的处理速度和网络的带宽,发送一个分组需要t毫秒时间,那么本来t4-t1这个时间间隔内最多可以发送(t4-t1)/t个分组报文,但因为停等的原因t4-t1这个时间间隔内只发送了一个分组报文,t4-t1-t的时间都被浪费在那里做等待了,所以网络带宽的利用率仅为 t/(t4-t1)*100%,当网络延时比较大的时候,则t4-t1的值很大的时候,网络的利用率就非常低,绝大部分时间都空闲在那里等待分组确认信息了。

       接下来,我们看一下TCP做为一个数据传输协议,如何改进停止等待协议,以提高网络利用率,来提高吞吐量(throughput)

B, 提高网络利用率,允许发送方在收到第一个分组等待确认前可以连续发送多个分组

        这个思路其实很简单,既然有t4-t1的时间空闲,那么我们允许发送方在收到“分组确认”之前继续发送多个分组,则可以把空停止等待期间的时间与网络带宽利用起来。如图可见t4-t1的时间内,此时发送了100个分组,我们继续假设发送一个分组需要t毫秒时间,那么网络的利用率就提高到100t/(t4-t1)*100%,为原来的100倍。

        同时如果每个分组都发回一个分组确认响应(ACK)的话,网络上会存在大量的分组确认响应(ACK)包,ACK包会占用大量的带宽,所以这里同时做了一个改进,减少ACK报文的数量。具体方法为在ACK信息里带上数字编号,表明小于这个数字的所有的包都已经正确接收,如图中“ACK(下一个包是1001)”表明1001之前的包都已经全部正确接收了,那么就减少了999个ACK报文。

        考虑t4-t1和t之间的关系,现实中,因为主机发送速度不同,网络的延时不同,t4-t1和t之前的数值关系可能会出现“100t>t4-t1”,在这种情况下,显然发送方不可以连接发送100个报文。那么问题就来了,我们该如何定义发送端在收到分组确认报文ack前可以连续发送多少个报文呢?这就需要在发送端引入滑动窗口的概念,根据当前窗口的大小来决定发送端在未收到新的一个ACK前可以最多再发送多少个分组报文。

C,理想网络中引入滑动窗口以控制发送方的发送速度

        为了简化理解,我们先认为网络是个理想网络,无抖动,不会丢包,不会乱序(即:数据包总是按发送的先后顺序到达接收方)。我们已经知道,在刚刚定义的理解网络中,只有发送方的发送速度大于接收方的接收速度的时候,我们才需要引入滑动窗口协议控制发送速度。

        这样的情况下,接收方通过ACK,对发送方的发送窗口大小进行控制,从而达到控制发送发发送速度的目的。我们先看一下滑动窗口的几个定义。

       我们给每个分组定义序号,如下图所示1,2,3,4.....(在TCP中序号表的是字节数,4就表示第4n个字节);图中方框(框住1-6的方框)是接收方通告给发送方的发送方的最大的发送窗口的大小(即提供的窗口),表明的发送方最多能够发送有6个已经发送但未接收到确认的分组(TCP中表示字节),此时,可用的窗口大小和最大发送窗口的大小是一至的。在窗口之外的(>7)的都定义为不能够发送

        当发送端启动发送了6个分组(TCP中为6n个字节),其中1-3个分组(TCP中为1n-3n个字节)已经发送并收到确认,4-6分组(TCP中为4n-6n个字节)已经发送但未收到确认后,此时提供的窗口大小不变还是6,但滑动到4-9的位置,此时4-6已经不可用,可用的窗口缩减为7-9,这表明这7-9是还能够发送的,如果发送端有发送要求,还可以继续利用这7-9进行发送。大于等于10的落在窗口之外,就算发送端有发送需求,也不能够发送,直到提供的窗口移动过来才可用。

        所以接收端通过给发送端发送回的ACK,来控制窗口的滑动,进而通过控制发送端剩余可以发送分组数量来控制接收端的发送速度,这就行成了上述定义的理想网络中的滑动窗口协议,完成发送速率控制。

 

        上图从左到右可以分割成4部分:发送并被确认,发送但未被确认,以够发送,不能够发送

发送但未被确认+能够发送,这二部分共同构成了提供的发送窗口的总大小。

D,真实网络中滑动窗口协议的改进

        真实的网络中,总是会存在丢包和乱序二种情况。那么丢包的就永远不会到达必须依赖发发送方重新发送,而乱序则意味着后发的报文可能会先到,接收方需要先把后发送的报文存起来,等待先发送的报文到达。

        TCP是面向连接的保证顺序的协议,所以TCP要确保在接收方分组报文是按照发送时的顺序被正确的重新组合起来后,再提供给上层应用的。

        所以窗口的滑动会受到丢包与乱序的影响,增加了三个指针(未收到确认的发送分组的起始点,下一个可发磅的分组编号,等待接收的分组报文的起始点),以及将C中的发送但未被确认的分成二部分:落在起始点后的未被确认的分组,和已经被确认的分组。

 

        如上图中,发送方能够清楚的知道4和5没有被确认,而6和7已经被确认,那么发送方可以清楚的知道要重新发送4和5,而不用重发6和7。

        以上是常规的滑动窗口协议的设计。

        在TCP中,考虑到重发,以及TCP是对每个字节编号,并且在 ACK总是回复确认序号(即确认序号之前的所有字节都已经被正确接收),而不是给每一个分组编号并给每一个分组产生ACK的。所以TCP的接收端总是回复“期待收到的下一个字节序号”。所以如上图中,收到6和7时都回复分组4的第一个字节的序号,表示分组4未收到,期待收到从分组4里的第一个字节的序号开始的数据,那么发送端就知道要重新发送4了。5也是同理,所以当4,5重发并都被正确接收后,接收端因为已经正确的接收了6和7了,就会直接发确认7+1=8的第一个字节的序号了,发送方就不会再生发6和7了。

        TCP协议以上述的滑动窗口协议为基础,通过4种具体的算法:慢启动、拥塞避免、快重传、快恢复、来达到尽可能提高TCP的吞吐量的目标。我们可以在后续的文章中,再进行介绍。

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

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

相关文章

摸鱼时间,画个吃豆人玩一下

Ⅰ . 吃豆人小游戏 Canvas API(画布)是在 HTML5 中新增的标签用于在网页实时生成图像;是一个非常适合,做一些有趣的小游戏 和 动画;下面我们来简单的写一下 这个小例子 👇 文章目录Ⅰ . 吃豆人小游戏Ⅱ. 实…

学习嵌入式必读十本书,从C语言到ARM

学习嵌入式必读的十本书籍,按照C语言、数据结构、Linux、C、QT、单片机、ARM的顺序给大家推荐。 01 C语言 凡是计算机、电子、通信、自动化、机械专业的同学,大一的时候必学C语言,而且大部分高校选择的教材都是谭浩强。这本书在网上的评价褒…

【计算机程序设计思想与方法】2 什么是计算思维?

1.2 什么是计算思维? 如《【计算机程序设计思想与方法】1 什么是计算?》中所述,计算是利用计算机一步一步地执行指令来解决问题的过程,计算机科学是关于计算的科学。 正如数学家在证明数学定理时,有独特的数学思维。工程师在设计制造产品时,有独特的工程思维。艺术家在…

【验证码逆向专栏】某验“初代”滑块验证码逆向分析

声明 本文章中所有内容仅供学习交流,抓包内容、敏感网址、数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 本文章未经许可禁止转载…

【算法】递归

目录1.递归概述2.何时使用递归2.1.定义是递归的2.2.数据结构是递归的2.3.问题的求解方法是递归的3.递归模型4.应用本文参考: 《数据结构教程》第 5 版 李春葆 主编 1.递归概述 (1)在定义一个过程或函数时,出现直接或者间接调用自…

【微服务】Elasticsearch文档索引库操作(二)

🚗Es学习第二站~ 🚩Es学习起始站:【微服务】Elasticsearch概述&环境搭建(一) 🚩本文已收录至专栏:微服务探索之旅 👍希望您能有所收获 一.索引库操作 索引库就类似数据库表,mapping映射就类…

DGIOT低代码场景部门的搭建过程

[小 迪 导读] : 通过低代码页面与konva 大屏的页面设计,围绕部门,实现应用场景快速搭建1.部门创建以及权限分配1.1 打开部门管理页面1.2新增部门1.3 权限分配,点击刚创建的部门,在菜单分配中选择总控台和设备管理(低代码平台会过滤掉非低代码…

Wandb:make visualization better than Tensorboard

Wandb:make visualization better than Tensorboard wandb :一个在线的可多人协作的多功能可视化工具包 我最开始使用的tensorboard,还写了一些相关tensorboard的脚本用于实验。tensorboard这里就不详细介绍了,相信大家都比较了解。直到尝试了…

【MySQL数据库入门】:表的约束

表的约束 真正约束字段的是数据类型,但是数据类型约束很单一,需要有一些额外的约束,更好的保证数据的合法性,从业务 逻辑角度保证数据的正确性。比如有一个字段是email,要求是唯一的。 表的约束很多,这里主…

版本管理之Git

一.版本控制器的方式1.1集中式版本控制工具集中式版本控制工具,版本库是集中存放在中央服务器的,team里每个人work时从中央服务器下载代 码,是必须联网才能工作,局域网或互联网。个人修改后然后提交到中央版本库。 举例&#xff1…

巧用回调函数解决微信小程序与后台数据交互出现的异步问题

问题描述 微信小程序端需要发送一个包含文字与图片的表单数据给后端,我一开始的思路是先上传图片得到临时的URL,后执行POST请求将表单数据发送给后端,但后端只能获取到文字,而图片URL却始终获取不到。 问题原因 注意看我上面的思路…

目标检测研究

传统的目标检测流水线 1.候选区域生成 通过滑动窗口选择感兴趣区域Rol;使用多尺寸的输入图像和多尺度的滑动窗口识别多尺度和不同比例的目标。 ⒉特征向量抽取 常用SIFT、 Harr、HOG、SURF。 3.区域分类 常用支持向量机。 结合集成、串联学习、梯度…

3D俯视角色割草游戏模板+视频教程,免费发布 | 一周精品推荐

大家好,我是晓衡。新年开工第一周,我就被热心的开发者们感动得热泪盈眶!今天我冒死推荐几款 Creator 游戏开发资源,希望能对得起这些开发者们,同时也希望你能也有所收获。3D俯视角割草游戏视频源码B 站 UP 主『好巧啊c…

MyBatis 数据查询语句中有关于大于,小于的书写方法 及 查询时相关sql 关键字

前言 提示:这里记录的大概内容: MyBatis 数据查询语句中有关于大于,小于的书写方法 一、MyBatis MyBatis 本是 apache 的一个开源项目 iBatis, 2010 年这个项目由 apache software foundation 迁移到了 google code,并且改名为…

Python封装、继承和多态

Python 语言在设计之初,就定位为一门面向对象的编程语言,“Python 中一切皆对象”。同时,Python 也支持面向对象的三大特征:封装、继承和多态。 一、封装 封装(Encapsulation),即在设计类时&am…

讲师邀请 | 在 DevData Talks,开放务实地聊聊研发效能!

什么是 DevData Talks? DevData Talks 是专注于研发效能实践经验与方法论的系列分享活动。 2022 年,我们既看到外部环境变幻莫测,也看到研发效能领域沉下心来稳步发展,从宏大的概念和价值,转向具体的问题&#xff0c…

若依框架代码自动生成器研究-表查询篇

最近生产环境用了一个开源系统:若依,其中有一个版块很有意思,很能提高生产效率: “代码生成器”。 其功能所处模块菜单为:系统工具->代码生成。我们来研究一下他的代码生成逻辑。 工具使用方法 1、建表 使用代码生成&#…

Python列表中你所不知道的事

1. 引言 目前,Python是世界上使用最广泛、最受欢迎的编程语言之一。Python丰富的功能性使它非常流行,因为我们可以使用它创建任何内容。我将在本博客中与大家分享关于Python列表的几条有趣的花絮。 闲话少说,我们直接开始吧! 2.…

如何高薪入职心仪的公司

序 本文首发自:稀土掘金、思否 我们从几个问题开始入手,来看一下本博客是否适合你: 如果你想要换工作,但是:制作的简历平平无奇如果你想要换工作,但是:投放了的简历总是无法得到 [心仪公司] 的…

SpringBoot+Vue茶叶商城系统

简介:本项目采用了基本的SpringBootVue设计的茶叶商城系统。详情请看主要截图。经测试,本项目正常运行。本项目适用于Java毕业设计、课程设计学习参考等用途。 项目描述 项目名称SpringBootVue茶叶商城系统源码作者LHL项目类型Java EE项目 (…