TCP详解(二)滑动窗口/流量控制

本文解释了TCP为何能保证数据传输的可靠性,以及如何保证整个网络的顺畅。

1 网络分层模型

这是一切的本质。网络被设计成分层的,所以网络的操作就可以称作一个“栈”,这就是网络协议栈的名称的由来。在具体的操作上,数据包最终形成的过程就是一层一层封装的过程,在栈上形成一段连续的数据,我们可以称作是一层一层的push操作。同样的,数据包的解封装的过程,则可以认为是一层一层的pop操作。

1.1 网络包的发送流程

  • 应用程序发送数据,调用send方法来将数据发送出去,此时便会触发系统调用来发送数据
  • 将用户数据从【用户空间】拷贝到【内核空间】,
  • 将数据封装为一个个【skb结构】(skb可以简单理解为一个封装待发送数据的数据结构,在内存层面待发送的数据都是以skb来表示并传递的。分配skb时会分配一个大小包含了所有协议头和数据长度的空结构,也就是最终发送出去的以太网帧的大小,随后经过不同协议层,不断的在skb中填充数据,为了防止不断扩充数组带来的消耗)
  • skb进入协议栈进行处理(分别经过传输层、网络层)
  • 然后skb会被传送到网卡【传输队列RingBuffer】里(网卡有多个队列,那么就有多个RingBuffer,并且每个队列对应一个发送队列一个接收队列),RingBuffer中存储的是skb的指针
  • 网卡将RingBuffer里面的数据真实的发送到网络上
  • 当网卡发送完数据后,网卡会向CPU发出一个数据发送完毕的【硬中断】
  • CPU响应该硬中断,找到硬中断处理函数,在硬中断处理函数里会发出软中断,然后由【内核线程ksoftirqd】去响应并处理软中断,【内核线程ksoftirqd】找到该软中断对应的处理函数(网卡驱动启动时注册的),然后进行调用,在处理函数中会清理RingBuffer
  • 等收到ack后会清理socket发送缓冲区

1.2 网络包的接收流程

网络包的接收流程主要涉及以下几个步骤:‌

  1. 网卡接收数据:‌当网络帧到达网卡时,‌网卡通过DMA(‌直接内存访问)‌方式将网络包放到收包队列中,‌并通过硬中断通知中断处理程序已经收到了网络包。‌
  2. 内核处理网络帧:‌网卡中断处理程序为网络帧分配内核数据结构(‌sk_buff)‌,‌并将其拷贝到sk_buff缓冲区中。‌然后通过软中断通知内核收到了新的网络帧。‌
  3. 协议栈处理:‌内核协议栈从缓冲区中取出网络帧,‌并通过网络协议栈从下到上逐层处理这个网络帧。‌例如,‌在链路层检查报文的合法性,‌找出上层协议的类型(‌IPv4还是IPv6)‌,‌去掉帧头、‌帧尾,‌然后交给网络层。‌
  4. 网络层处理:‌网络层取出IP头,‌判断网络包下一步的走向,‌如果是要发送到本机,‌则取出上层协议的类型(‌TCP或UDP)‌,‌去掉IP头,‌再交给传输层处理。‌
  5. 传输层处理:‌传输层取出TCP头或UDP头后,‌根据<源IP、‌源端口、‌目的IP、‌目的端口>四元组作为标识,‌找出对应的Socket,‌并把数据拷贝到Socket的接收缓存中。‌
  6. 应用程序读取数据:‌最后,‌应用程序可以使用Socket接口读取到新接收到的数据。‌

1.3 socket缓冲区

TCP的socket缓冲区是TCP协议为了实现可靠的数据传输而在内存中分配的临时存储区域,每个TCP socket连接都有两个缓冲区:发送缓冲区(send buffer)和接收缓冲区(receive buffer)。只要建立TCP连接,这两个缓冲区就会默认建立。

  • 发送缓冲区(Send Buffer): 发送缓冲区用于暂存应用程序打算通过TCP连接发送出去的数据。当应用程序调用send()或write()函数将数据写入socket时,数据并不会立即被发送到网络上,而是首先被放入发送缓冲区。TCP协议负责从缓冲区中取出数据,根据当前的网络状况和拥塞控制等因素逐步将数据发送到目标主机。如果发送缓冲区满,应用程序的写操作可能会被阻塞(在阻塞模式下)或者返回错误(在非阻塞模式下)。
  • 接收缓冲区(Receive Buffer): 接收缓冲区用于存储从网络中接收到但尚未被应用程序读取的数据。当数据包从网络到达时,TCP协议将它们放入接收缓冲区,等待应用程序通过recv()或read()函数读取。如果缓冲区满了而新的数据继续到达,超出部分的数据可能会被丢弃,或者根据TCP的流量控制机制暂时停止对方发送更多数据,以避免数据丢失。

2 滑动窗口

2.1 窗口详情

滑动窗口协议属于TCP协议的一种应用,用于网络数据传输时的流量控制,以避免拥塞的发生。该协议允许发送方在停止并等待确认前发送多个数据分组。由于发送方不必每发一个分组就停下来等待确认,因此该协议可以加速数据的传输,提高网络吞吐量。

TCP通过滑动窗口来进行流量控制。设想在发送端发送数据的速度很快而接收端接收速度却很慢的情况下,为了保证数据不丢失,显然需要进行流量控制, 协调好通信双方的工作节奏。所谓滑动窗口,可以理解成接收端所能提供的缓冲区大小。TCP利用一个滑动的窗口来告诉发送端对它所发送的数据能提供多大的缓冲区。由于窗口由16位bit所定义,所以接收端TCP 能最大提供65535个字节的缓冲。由此,可以利用窗口大小和第一个数据的序列号计算出最大可接收的数据序列号。

滑动窗口本质上是描述接受方的TCP数据报缓冲区大小的数据,发送方根据这个数据来计算自己最多能发送多长的数据。如果发送方收到接受方的窗口大小为0的TCP数据报,那么发送方将停止发送数据,等到接受方发送窗口大小不为0的数据报的到来。

TCP建立连接的初始,B会告诉A自己的接收窗口大小,比如为‘20’:字节31-50为发送窗口。

根据B给出窗口值,A构造自己的窗口

A发送11个字节后,发送窗口位置不变,B接收到了乱序的数据分组,因为最左侧31没收到,即使32、33收到了,给A返回的ack中的窗口依旧不变,也就是B只会返回收到的连续的字节数

只有当A成功发送了数据,即发送的数据得到了B的确认之后,才会移动滑动窗口离开已发送的数据;同时B则确认连续的数据分组,对于乱序的分组则先接收下来,避免网络重复传递,等31也收到后才会在ack中返回seq为34(下次接收的字节编号),同时窗口向右移动+3

如果34一直没收到,A会将剩余的窗口数据继续传过去,然后就不能在发送了

当B接收到所有数据后,假如应用程序一直未取数据,那就导致接收缓冲区中所有的数据都是待交付主机的状态,窗口也就是会变成0,ack就会为 seq=54,win=0

2.3 最大窗口限制

TCP的Window是一个16bit位字段,它代表的是窗口的字节容量,也就是TCP标准窗口最大为2^16 -1 = 65535个字节。

另外在TCP的选项字段中还包括了一个TCP窗口扩大因子,option-kind 为 3 ,option-length为 3 个字节(总字节数),option-data只占一个字节,取值范围 0 -14.窗口扩大因子用来扩大TCP窗口,可把原来16bit的窗口,扩大为31bit,这个在上一篇文章中解释过,详情请看 TCP详解(一)报文详情/MSS/MTU-CSDN博客

3 流量控制

所谓流量控制,主要是接收方传递信息给发送方,使其不要发送数据太快,是一种端到端的控制。主要的方式就是返回的ACK中会包含自己的接收窗口的大小,并且利用大小来控制发送方的数据发送

3.1 持续计时器

这里面涉及到一种情况,如果B已经告诉A自己的缓冲区已满,于是A停止发送数据;等待一段时间后,B的缓冲区出现了富余,于是给A发送报文告诉A我的rwnd大小为400,但是这个报文不幸丢失了,于是就出现A等待B的通知||B等待A发送数据的死锁状态。为了处理这种问题,TCP引入了持续计时器(Persistence timer),当A收到对方的零窗口通知时,就启用该计时器,时间到则发送一个1字节的探测报文,对方会在此时回应自身的接收窗口大小,如果结果仍未0,则重设持续计时器,继续等待。

TCP为每一个连接设有一个持续计时器。只有TCP的一方收到对方的零窗口通知,就启动持续计时器;只要持续计时器超时,就放送一个零窗口探测报文,携带一字节的数据;而对方收到零窗口探测报文时,回复自己现有的接收窗口值。如果窗口大小依旧是零,那么收到报文的一方就重新启动持续计时器。

持续计时器是为了解决双方相互等待(A等待B发送非零窗口的通知,B等待A发送数据)而形成的死锁现象。这种现象一般发生在发送窗口大小数据包丢失时。

3.2 RTT

RTT,全称Round Trip Time,即往返时间,数据发送时刻到接收到确认的时刻的差值。由链路传播时间、末端系统处理时间、路由器缓存中排队和处理的时间组成。

对于TCP来说,路由器缓存中排队和处理的时间会随着网络拥塞程度辩护而变化。通过计算RTT可以反应网络拥塞程度,从而拥塞控制。

3.3 RTO

RTO,全称Retransmission TimeOut,即重传超时时间即从数据发送时刻算起,超过这个时间便执行重传。。

超时之后TCP进入Loss状态,重传所有没有被确认的报文,同时进入慢启动的回复过程。

重传的时间RTO设定是非常重要的,如果设置太短,可能会导致并没有丢包而重传,如果设置太长了,可能因为等待ACK而浪费掉很多时间,牺牲传输的效率。从思想上来讲,其实我们还是希望重传的时间需要稍稍的大于RTT就可以了。但是这个RTT没有什么可以使用的定值,他是不断变化的,所以只能动态的进行设置,RTO只能是根据RTT来进行动态的设置

3.4 拥塞

随着网络上的主机不断增加其发送速率,会使整个网络变得非常拥挤;这会导致网络经常出现丢包现象,使网络传输效率大幅度下降。

如果不对网络做拥塞控制,会降低整个网络的传输效率

3.5 慢启动和拥塞控制

(1)一条TCP连接开始时,window size被设置为1 MSS(最大报文段大小)

(2)TCP发送方发送完发送窗口数据,并收到所有的确认,window size以指数增长(以2的倍数进行翻倍),即慢启动阶段。

(3)window size增长到一个慢启动的阈值thresh,开始执行拥塞控制算法(window size呈线性增长),进入拥塞控制阶段。

(4)随着window size增长,发送速率提高,出现网络拥塞,分组超时重传。比如丢包时,将慢启动门限设置为原来的一半,然后将cwnd设置为1,然后执行慢启动算法(起点较低,指数级增长)

上述方法的目的是在拥塞发生时循序减少 主机发送到网络中的分组数,使得发送拥塞的路由器有足够的时间去把队列中积压的分组处理完毕。

慢启动和拥塞控制算法常常作为一个整体使用,

3.6 快重传和快恢复

1990增加新的拥塞控制算法:快重传和快恢复。用于改进TCP的性能。

有时候,个别报文会在网络中丢失,当实际上网络并没有发生拥塞,这将导致发送方超时重传并认为网络出现了拥塞;从而错误的启动慢启动算法,因此降低传输效率。为此,引入快重传算法,可以让发送方尽早知道个别报文段的丢失。

所谓快重传,就是发送方尽快的进行重传,而不是等超时计时器超时才重传。快重传可以使整个网络吞吐量提高约20%。发送方接收到3个重复确认,就知道只丢失了个别报文段,于是不启动慢启动算法,而是执行快恢复算法。具体方式如下

  1. 当接受方建立这样的机制,如果一个包丢失,则对后续的包继续发送针对该包的重传请求
  2. 一旦发送方接收到三个一样的确认,就知道该包之后出现了错误,立刻重传该包;
  3. 此时发送方执行“快恢复”算法:①慢启动门限减半②CWND设为慢开始门限减半后的数值③执行拥塞避免算法(高起点,线性增长)

所谓快恢复,就是发送方将慢启动上限和拥塞窗口值调整为当前窗口的一半,开始执行拥塞避免算法。

快重传和快恢复是为了提高TCP传输的效率和可靠性

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

20. OTA流程 - 2

1. 概述 BES蓝牙方案自带OTA功能,支持SPP和BLE。 建议采用BLE的功能,因为苹果手机默认不支持SPP。 2. OTA框架 OTA时,耳机端需要先进入OTA状态 2.1 SPP升级

Nginx--代理与负载均衡(扩展nginx配置7层协议及4层协议方法、会话保持)

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 一、代理原理 1、反向代理产生的背景 单个服务器的处理客户端&#xff08;用户&#xff09;请求能力有一个极限&#xff0c;当接入请求过多时&#…

【网络安全】SSO登录过程实现账户接管

未经许可,不得转载。 文章目录 正文正文 登录页面展示了“使用 SSO 登录”功能: 经分析,单点登录(SSO)系统的身份验证过程如下: 1、启动SSO流程:当用户点击按钮时,浏览器会发送一个GET请求到指定的URL: /idp/auth/mid-oidc?req=[UNIQUE_ID]&redirect_uri=[REDI…

Leetcode JAVA刷刷站(41)缺失的第一个正数

一、题目概述 二、思路方向 为了找到未排序整数数组中未出现的最小正整数&#xff0c;并满足时间复杂度为 O(n) 和只使用常数级别额外空间的要求&#xff0c;我们可以采用原地哈希&#xff08;也称为索引哈希&#xff09;的方法。这个方法的基本思想是将每个数字&#xff08;如…

[C++进阶]二叉树进阶的一些面试题(一)

首先我们先回忆我们过去学的二叉树和最近学的二叉搜索树,来完成下面的题目: 606. 根据二叉树创建字符串 这道题属于与基础题,首先我们观察输入输出样例可以得到如果root->left为空,root->right不为空时,我们的空格仍然需要保留,如果当前节点有两个孩子&#xff0c;那我…

人工智能在肿瘤亚型分类领域的研究进展|顶刊速递·24-08-13

小罗碎碎念 文献日推主题&#xff1a;人工智能在肿瘤亚型分类领域的研究进展 昨天晚上在研究鼻咽癌的病理学诊断指南&#xff0c;看到了下面这段话的时候&#xff0c;我问了自己一个问题——通过AI识别出肿瘤亚型的根本目的是什么&#xff1f;可以衔接哪些具体的下游任务&#…

TinyEngine是什么?

TinyEngine 是 OpenTiny 项目下的一个开源低代码引擎&#xff0c;旨在帮助开发者快速构建应用程序。它提供了可视化搭建页面的能力&#xff0c;支持在线实时构建和二次开发或集成&#xff0c;适用于多种场景的低代码平台开发&#xff0c;例如资源编排、服务端渲染、模型驱动、移…

拉取/启动kafka的docker镜像

拉取/启动kafka的docker镜像 1、拉取kafka镜像2、移除docker镜像(演示)3、查看镜像是否拉取成功4、通过docker启动kafka容器5、查看是否有启动的容器 1、拉取kafka镜像 因为一些原因&#xff0c;无法从dockerhub直接拉取kafka的docker镜像&#xff0c;我将原来拉到kafka3.7.0的…

后端开发刷题 | 寻找峰值【二分法】

描述 给定一个长度为n的数组nums&#xff0c;请你找到峰值并返回其索引。数组可能包含多个峰值&#xff0c;在这种情况下&#xff0c;返回任何一个所在位置即可。 1.峰值元素是指其值严格大于左右相邻值的元素。严格大于即不能有等于 2.假设 nums[-1] nums[n] −∞ 3.对于…

MQ死信对列

面试题&#xff1a;你们是如何保证消息不丢失的&#xff1f; 1、什么是死信 死信就是消息在特定场景下的一种表现形式&#xff0c;这些场景包括&#xff1a; 1. 消息被拒绝访问&#xff0c;即消费者返回 basicNack 的信号时 或者拒绝basicReject 2. 消费者发生异常&#xff0…

保存数据至后台表

保存数据至后台表-供大数据平台使用-JOB程序 *&---------------------------------------------------------------------* *&程序名称 &#xff1a;ZBD_JOB_001 *&程序描述 : 保存数据至后台表-供大数据平台使用-JOB程序 *…

数据结构:线性结构之顺序表、链表篇

数据结构&#xff1a;顺序表、链表篇 线性表一、顺序表&#xff08;一&#xff09;顺序表的结构定义&#xff08;二&#xff09;顺序表的功能实现1、初始化2、销毁3、扩容4、插入5、删除 &#xff08;三&#xff09;顺序表例题分析1、删除有序数组中的重复项2、合并两个有序数组…

大数据技术——DolphinScheduler的集群部署

目录 第1章 DolphinScheduler简介 1.1 DolphinScheduler概述 1.2 DolphinScheduler核心架构 第2章 DolphinScheduler部署说明 2.1 软硬件环境要求 2.1.1 操作系统版本要求 2.1.2 服务器硬件要求 2.2 部署模式 2.2.1 单机模式 2.2.2 伪集群模式 2.2.3 集群模式 第3章…

进程间通信—无名管道

gg shiftg快速对齐 加锁顺序问题时&#xff0c;如果解锁了&#xff0c;两个同时申请抢锁&#xff0c;谁抢到了运行谁&#xff0c;循环迭代时释放锁也是同时申请锁&#xff0c;循环部分如果没抢到锁就进入循环等待 总结: IPC 进程间通信 interprocess communicate //signal…

免费简单的制作3D卡通建模——Fuse软件和Readyplayer的使用介绍

最终效果 文章目录 最终效果一、使用Fuse软件去Steam下载安装捏人选择身体部位自定义人物细节参数换装贴图修改导出OBJ文件即可 二、使用ReadyplayerReadyplayer官网地址选择从模板开始&#xff0c;或者拍照选择图片进行捏脸将模型导入Unity通过Readyplayer官方插件导入模型通过…

UI设计:蒸汽波风格页面有啥特征,应用哪些场景?

一、什么是蒸汽波风格 蒸汽波风格&#xff08;Steampunk&#xff09;是一种将19世纪工业时代的技术和想象力与未来科技相结合的艺术和文化流派。它通常描绘了一个类似维多利亚时代的世界&#xff0c;其中蒸汽动力是主要能源&#xff0c;机械装置和复杂的齿轮系统被广泛应用。 …

若依服务器上云部署

准备条件&#xff1a;安装好mysql和redis并配置好密码。 1.安装JDK&#xff0c;我这里使用的是1.8 wget --no-check-certificate --no-cookies --header "Cookie: oraclelicenseaccept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u131-b11/…

idea 对于mybatis-plus框架JRebelX和XRebel热启动失效问题

1.mybatis-plus不需要使用热启动插件&#xff0c;修改完代码后&#xff0c;直接重新编译一下即可&#xff0c;不需要重启 2.如果是mapper.xml文件&#xff0c;则直接安装JRebel MybatisPlus extension 插件即可完成mapper.xml静态文件更改进行热加载

XSS小游戏(题目+解析)DOM破坏!!!

文章目录 一、Ma Spaghet!二、Jefff三、Ugandan Knuckles四、Ricardo Milos五、Ah Thats Hawt六、Ligma七、Mafia方法一&#xff1a;可以用匿名函数来试试方法二&#xff1a;利用toString方法方法三&#xff1a;利用location和hash切片slice 八、Ok, Boomer九、svg十、DOM破坏十…

阿里巴巴Arthas详解

Arthas 是 Alibaba 在 2018 年 9 月开源的 Java 诊断工具。支持 JDK6&#xff0c; 采用命令行交互模式&#xff0c;可以方便的定位和诊断线上程序运行问题。Arthas 官方文档十分详细&#xff0c;详见&#xff1a;arthas Arthas使用场景 得益于 Arthas 强大且丰富的功能&#x…