【Linux网络】详解TCP协议(3)

news2024/11/16 23:34:38
图片名称
🎉博主首页: 有趣的中国人

🎉专栏首页: Linux网络

🎉其它专栏: C++初阶 | C++进阶 | 初阶数据结构

在这里插入图片描述

小伙伴们大家好,本片文章将会讲解 TCP的流量控制和滑动窗口 的相关内容。


如果看到最后您觉得这篇文章写得不错,有所收获,麻烦点赞👍、收藏🌟、留下评论📝。您的支持是我最大的动力,让我们一起努力,共同成长!

文章目录

  • `1. 流量控制`
    • ==<font color = blue><b>🎧1.1 流量控制是什么🎧==
    • ==<font color = blue><b>🎧1.2 如何控制发送方的速度🎧==
  • `2. 滑动窗口`
    • ==<font color = blue><b>🎧2.1 什么是滑动窗口🎧==
    • ==<font color = blue><b>🎧2.2 深入理解滑动窗口🎧==



上一篇文章中,博主介绍了 :

  • TCP 的三次握手和四次挥手;

建议将上一篇文章看完之后再来看这篇文章,链接如下:

【Linux网络】详解TCP协议(2)

那么接下来正片开始:



1. 流量控制


🎧1.1 流量控制是什么🎧


  • 接收端处理数据的速度是有限的, 如果发送端发的太快, 导致接收端的缓冲区被打满, 这个时候如果发送端继续发送, 就会造成丢包;
  • 继而引起丢包重传等等一系列连锁反应;
  • 因此 TCP 支持根据接收端的处理能力, 来决定发送端的发送速度。 这个机制就叫做流量控制(Flow Control)。
  • 总的来说就是根据接收方的接受能力控制发送方发送数据的速度。

🎧1.2 如何控制发送方的速度🎧


  • 如何控制发送方的发送数据的速度分为两种情况:
    • 一种是接收方接收缓冲区太大;
    • 另一种是接收方接收缓冲区太小。

16位窗口大小

  • 首先回顾一下TCP报头:

在这里插入图片描述

  • 在报头中存在 16位窗口大小,这个窗口大小就是接收方用来通知发送方它的接收缓冲区大小而存在的。
  • 当接收方接收缓冲区大,回复的ACK中的窗口大小就大,反之亦然;

那么这个时候很多人可能会有一个疑问,那么在发送方第一次给接收方发送消息的时候是怎么知道窗口大小的呢?

  • 其实虽然是第一次发送消息,但是他们双方在三次握手建立连接的时候,接收方就已经给发送方发送了携带ACK的数据包;
  • 这个时候就已经给发送方通告了接收方接收缓冲区的大小。
  • TCP报文中窗口大小是16位的,那么最大的窗口大小就是 2 16 − 1 = 65535 ( K B ) 2^{16} - 1 = 65535 (KB) 2161=65535(KB),但是真的是这样的吗;
  • TCP报头中,除了 20Byte 的固定的TCP报头大小,还有个40Byte的选项,在这里面包含了窗口扩大因子M实际上的窗口大小就是窗口字段的值左移M位。

PSH 标志位

  • 当接收方接收缓冲区的大小很小,甚至为 0 0 0 的时候,怎么办呢?一般有三种做法:
  • 首先当窗口大小为 0 0 0 的时候,如果过了一段时间接收方的接收缓冲区扩大了,就会给发送方发送一个窗口更新通知,告诉发送方可以发送数据了;
  • 当然,如果过了超时重传的事件之后,方式方还没有接收到窗口大小变化的通知,发送方也会不断地向接收方发送窗口探测的数据包,如果发现接收方回复的ACK的数据包中窗口大小变大了,就会发送数据了;
  • 但是如果接收方的接收缓冲区长时间没有变化,发送方也会发送一个带有PSH标志位的报文,通知接收方得快速地处理接收缓冲区中的数据。

URG标志位

这样看来,我们已经学习了五个标志位,就差最后一个URG标志位了,那我们就来讲解一下URG标志位吧!

  • 如果在TCP报头中URG标志位置 1,说明报头中的16位紧急指针是有效的;
  • 这个紧急指针代表着在TCP的数据中,和首位置的偏移量是多少
  • 一般在TCP中紧急数据只能有 1 B y t e 1 Byte 1Byte

send()recv() 系统调用中都有紧急数据的设置,我们再来看一下接口:

  • ssize_t send(int sockfd, const void *buf, size_t len, int flags);
    • 使用 send() 系统调用发送数据时,可以选择将带外数据发送到指定的套接字。通过设置标志参数中的 MSG_OOB可以标识要发送的带外数据
    • 其中,flags 参数可以传递 MSG_OOB,以指示发送的字节是带外数据。
  • ssize_t recv(int sockfd, void *buf, size_t len, int flags);
    • 使用 recv() 系统调用接收数据时,也可以指定标志以接收带外数据。通过设置标志参数中的 MSG_OOB接收方可以读取带外数据
    • 其中,flags 参数可以传递 MSG_OOB以指示接收带外数据


2. 滑动窗口



在讲解完流量控制和超时重传机制,其实还是有两个问题:

  • 发送方如何根据接收方的窗口大小发送数据呢?
  • 超时时间内,数据并没有被丢弃,那存储在哪里了呢?


为了理解这两个问题,我们得先学习滑动窗口。


🎧2.1 什么是滑动窗口🎧


  • 博主在 TCP第一篇文章 中讲过,发送方可以一次性给接收方发送多条数据,例如下图:

在这里插入图片描述

  • 这样发送数据就可以大大提高效率,因为可以在一个时间段发送多条数据。
  • 而发送方就规定一个概念:滑动窗口,并且在滑动窗口内的数据可以直接发送,暂时不用收到应答。
    • 在窗口左侧的数据就是已发送,已确认了的;
    • 在窗口右侧的数据就是未发送,未确认;
    • 在窗口中的数据就是等待发送的数据。
  • 而滑动窗口的大小就是对方同步给我的接收缓冲区的大小,即对方的接受能力(暂时)。

滑动窗口抽象图

在这里插入图片描述


🎧2.2 深入理解滑动窗口🎧



那么依然有几个问题:

滑动窗口可以变大吗?
滑动窗口可以变小吗?
滑动窗口可以向左移动吗?

OK,那么接下来就来解答这几个问题。


  • 滑动窗口本质上就是对方接受能力的大小,即对方接收缓冲区的大小;
  • 所以如果对方接受能力变大,那么滑动窗口就会变大,反之亦然
  • 如果对方的接收缓冲区中已经没有空间了,即对方接收缓冲区满了,那么滑动窗口的大小自然就变成了 0 0 0
  • 滑动窗口是不能向左滑动的。因为在窗口左边的数据是已发送已确认了的,所以就不可能再重新发送一次了

滑动窗口表示方法

  • 博主之前讲解过,缓冲区可以想象成一个很大的数组,那么缓冲区中的每一个数据就天然有了一个下标;
  • 那么滑动窗口中的数据就也有自己的下标;
  • 当接收方给我回复ACK的时候,在TCP报头中有确认序号,所以这个序号就可以代表窗口的起始地址,而报头中窗口的大小就是滑动窗口的大小
  • 这样我们就可以用几行代码表示窗口的起始地址以及结束地址:
    • win_start = ack_seq;
    • win_end = win_start + win_size;
    • 这样我们就可以直观的理解什么是窗口的变大、变小甚至为 0 0 0,以及为什么不能向左移动;
  • 当然缓冲区的大小不可能是无穷大的,所以在底层应该使用环形队列来实现的,可能会用取模运算来实现

滑动窗口丢包问题

如果滑动窗口中有数据丢包应该怎么办呢?丢包起始可以分成三种情况:

  • 头部丢包;
  • 中间丢包;
  • 为不丢包;
  • ACK丢包

先来看一下头部丢包:

在这里插入图片描述

  • 确认序号的定义是表示接收端这个序号之前的所有数据我已经收到了;
  • 那么假设头部丢包,接收方发给发送方的TCP报文中,确认序号就一直是 0 0 0(上图的情况)。
  • 那么发送方接收到所有报文中确认序号就都是 0 0 0(上图的情况);
  • 当发送方接收到连续三条相同的确认应答,就会进行重传;
    • 这种机制叫做快速重发机制,又称为快重传。
    • 快重传机制和超时重传机制并不冲突,超时重传机制相当于是给快重传机制兜了底。
  • 上图如果发生了快重传,并且接收方接收到了数据,那么下一次的确认序号就是 8001 8001 8001

中间数据和尾部数据丢包:

  • 当中间数据或者尾部数据丢包,那么发送方收到的确认序号就是丢包的那个部分的开始序号
  • 由于滑动窗口的起始地址就是等于确认序号,因此丢包的那部分数据就变成了头部,进而全部转换成了头部数据丢包。

ACK丢包:

在这里插入图片描述

  • 这种情况并不要紧,因为可以通过后续的ACK确认接收方是否收到了。

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

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

相关文章

VB.net读写NDEF标签URI智能海报WIFI蓝牙连接

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?ftt&id615391857885 Public Class Form1Dim oldpicckey(0 To 5) As Byte 卡片旧密码Dim newpicckey(0 To 5) As Byte 卡片新密码Function GetTagUID() As StringDim status As ByteDim myctrlword As …

Android手机投屏方案实现方式对比

文章目录 1.概述2.术语解释2.1 miracast2.2 scrcpy2.4 Wifi Direct2.5 app_process 3.技术实现对比3.1 Miracast3.1.1 Miracast介绍3.1.2 Miracast原理3.1.3 Miracast优缺点分析 3.2 Scrcpy3.2.1 scrcpy 介绍3.2.2 scrcpy的实现原理3.2.3 scrcpy的优缺点分析 3.3 Google cast3.…

Nisshinbo日清纺pvs1114太阳模拟器手测

Nisshinbo日清纺pvs1114太阳模拟器手测

影响上证50股指期货价格的因素有哪些?

上证50股指期货&#xff0c;作为反映上海证券交易所最具代表性50只股票整体表现的期货合约&#xff0c;其价格同样受到一系列复杂因素的驱动。以下是对影响上证50股指期货价格的主要因素进行的详细分析。 因素一、期货合约的供求关系 股指期货市场是一个由多头和空头双方共同…

关于AI副业,能说的都说了(最核心3大赛道、机会、方向)

AI&#xff0c;是生产力工具~ AI&#xff0c;也是焦虑和痛点 一直有小伙伴在问AI副业的事儿&#xff0c;之前也分享过很多。 但是&#xff0c;很多人对AI于副业的作用&#xff0c;过于表面和形式&#xff0c;所以&#xff0c;狂金来叨叨一下最核心的3大赛道&#xff0c;希望…

腾讯云SDK购买流程

音视频终端 SDK 需购买对应 License/套餐获得使用授权&#xff0c;本文将对购买 License/套餐的操作进行详细指引。 您可首先参考计费概述 确认您需要购买的内容&#xff0c;随后参考本文进行购买。本文仅提供 SDK 授权费用所需资源的购买&#xff0c;如果您需要使用其他相关云…

深入浅出MySQL事务处理:从基础概念到ACID特性及并发控制

1、什么是事务 在实际的业务开发中&#xff0c;有些业务操作要多次访问数据库。一个业务要发送多条SQL语句给数据库执行。需要将多次访问数据库的操作视为一个整体来执行&#xff0c;要么所有的SQL语句全部执行成功。如果其中有一条SQL语句失败&#xff0c;就进行事务的回滚&a…

回答网友一个数据显示的问题

事情是这个样子的 俺在一个C# 群里&#xff0c;一个问:"打开form2&#xff0c;可以同步显示form1的表格内容&#xff0c;在form2增删改表格内容之后&#xff0c;可以同步到form1中"。 俺 打开 delphi 放了几个 数据敏感 控件&#xff0c;演示了一下。还说了 一行…

Windows环境下训练开源图像超分项目 ECBSR 教程

ECBSR 介绍 ECBSR&#xff08;Edge-oriented Convolution Block for Real-time Super Resolution&#xff09;是一种针对移动设备设计的轻量级超分辨率网络。它的核心是一种可重参数化的构建模块&#xff0c;称为边缘导向卷积块&#xff08;ECB&#xff09;&#xff0c;这种模…

数集相等定义凸显“R各元x的对应x+1的全体=R”是几百年重大错误

黄小宁 变量x所取各数也均由x代表&#xff0c;x代表其变域&#xff08;x所有能取的数组成的集&#xff09;内任一元。设集A&#xff5b;x&#xff5d;表A各元均由x代表&#xff0c;&#xff5b;x&#xff5d;中变量x的变域是A。其余类推。因各数x可是数轴上点的坐标所以x∈R变换…

详解ES5中的数组方法

7.9 ES5中的数组方法 ECMAScript 5定义了9个新的数组方法来遍历、映射、过滤、检测、简化、搜索数组。 7.9.1 forEach() 7.9.2 map() 将调用的数组的每个元素传递给指定的函数&#xff0c;并返回一个数组&#xff0c;包含函数的返回值。 例如数组的每个元素的立方&#xf…

基于SpringBoot+Vue的大学生勤工助学兼职管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…

【优选算法】(第八篇)

目录 串联所有单词的⼦串&#xff08;hard&#xff09; 题目解析 讲解算法原理 编写代码 最⼩覆盖⼦串&#xff08;hard&#xff09; 题目解析 讲解算法原理 编写代码 串联所有单词的⼦串&#xff08;hard&#xff09; 题目解析 1.题目链接&#xff1a;. - 力扣&#…

防砸安全鞋这样挑,舒适又安心!

在复杂多变的工作环境中&#xff0c;安全始终放在首位&#xff0c;特别是对于那些在工地、车间等危险环境中工作的朋友们来说&#xff0c;一双好的防砸安全鞋无疑是工作中的“守护神”。然而&#xff0c;市面上的防砸安全鞋种类繁多&#xff0c;如何挑选一双既舒适又安心的鞋子…

unreal engine5制作动作类游戏时,我们使用刀剑等武器攻击怪物或敌方单位时,发现攻击特效、伤害等没有触发

UE5系列文章目录 文章目录 UE5系列文章目录前言一、问题分析二、解决方法1. 添加项目设置碰撞检测通道2.玩家角色碰撞设置3.怪物角色碰撞预设 最终效果 前言 在使用unreal engine5制作动作类游戏时&#xff0c;我们使用刀剑等武器攻击怪物或敌方单位时&#xff0c;发现攻击特效…

10.C++程序中的循环语句

C中提供了三种循环语句&#xff08;for循环&#xff0c;while循环以及do-while循环)来使程序员可以更方便地对数据进行迭代操作。 if语句 for语句的格式为&#xff1a; for(初始化语句&#xff1b;循环条件&#xff1b;迭代语句&#xff09; &#xff5b; 代码块 &#x…

网上找旅游搭子靠谱吗?分享国庆与旅行搭子出行的冒险记

国庆将至&#xff0c;我那颗渴望旅行的心愈发躁动不安。一直想在这个难得的假期里去领略祖国的大好河山&#xff0c;思来想去&#xff0c;决定去神秘而美丽的张家界。然而&#xff0c;身边的朋友不是已有安排&#xff0c;就是对这个目的地不感兴趣。无奈之下&#xff0c;我只好…

ArcGIS与ArcGIS Pro去除在线地图服务名单

我们之前给大家分享了很多在线地图集&#xff0c;有些地图集会带有制作者信息&#xff0c;在布局制图的时候会带上信息影响出图美观。 一套GIS图源集搞定&#xff01;清新规划底图、影像图、境界、海洋、地形阴影图、导航图 比如ArcGIS&#xff1a; 比如ArcGIS Pro&#xff1a…

书生大模型实战(从入门到进阶)L2-茴香豆:企业级知识库问答工具

目录 茴香豆介绍 茴香豆本地标准版搭建 环境搭建 配置服务器&#xff1a; 搭建茴香豆虚拟环境&#xff1a; 安装茴香豆 下载茴香豆 安装茴香豆所需依赖 下载模型文件 更改配置文件 知识库创建 测试知识助手 命令行运行 Gradio UI 界面测试 本文是对书生大模型L2-茴香…

电脑录屏怎么录视频和声音?苹果macOS、windows10都可以用的原神录屏工具来啦

在当今数字化时代&#xff0c;电脑录屏已经成为一项非常实用的技能&#xff0c;无论是制作教学视频、记录游戏精彩瞬间&#xff0c;还是进行线上会议演示&#xff0c;都离不开高质量的录屏。那么&#xff0c;电脑录屏怎么录视频和声音呢&#xff1f;今天就为大家详细介绍一下&a…