TCP 核心工作机制

TCP 的核心知识:如何保证传输可靠 + 如何提高传输效率

如何保证传输可靠:确认应答机制 + 超时重传机制

如何提高传输效率:滑动窗口机制、流量控制机制、延时应答机制、捎带确认机制、拥塞控制机制

可靠机制

        TCP的可靠性主要是通过 确认应答 + 超时重传 来体现的。

1.确认应答机制

        先看发送发:在没有滑动窗口机制之前,发送方一次只能发送一段报文,且每次发送完后要等待接收方的ACK确认,只有在收到接收方的ACK确认应答后,才能将发送缓冲区里对应的数据释放掉,并开始发送第二段报文。如果在规定时间内未收到ACK确认,则尝试重传这段报文(超时重传机制)。

        再看接收方:接收方每次接收到报文后,都要给发送方返回一个确认应答报文ACK,告知对方已正确接收数据,期望下次收到报文段的起始序列号是ack。

        确认应答机制本质上是接收方对发送方报文中的seq进行确认,TCP是字节流传输协议,seq就代表数据,seq被确认就意味着数据被确认。只有确认应答机制 + 超时重传机制才能保证数据传输的可靠性,但数据传输效率比较低(RTT时间越长,传输效率越低)

2.重传机制

2.1 超时重传机制

        TCP超时重传机制是针对确认应答阶段数据丢包的情况,TCP传输过程中,发送方发出的报文可能会丢失,接收方返回给对端的ACK报文也有可能丢失。无论是哪种丢包,发送方在发送完报文后如果在指定时间内(RTO,Retransmission Timeout 超时重传时间)未收到对端返回的ACK报文,就会重传这段报文。重传次数达到一定量时,如果还是无法收到ACK报文,发送方就会发送RST报文,要求重置连接,如果重置连接都失败那就彻底断开连接。

RTO随RTT动态变化。RTT越小,网络环境越好,RTO也随之变小。

如果超时重传的数据,因再次超时而重传时,超时重传时间将是先前值的两倍。

        接收方收到重复的报文怎么办?TCP接收数据时都先将数据写入到接收缓冲区(Receive Buffer),再根据seq对缓冲区数据进行排序,方便应用程序正确有序地读取数据。新接收到的数据在写入缓冲区后,自然也要根据seq排序,这时就很容易判断出这段数据是否重复,如果重复就直接丢弃,这种机制确保了应用层读取到的数据是有序且不重复的。

        超时重传存在的问题是,超时周期相对较长。

2.2 快速重传机制

        快速重传(Fast Retransmit)机制,本质还是为了提高传输效率,它不以时间为驱动,而是以数据驱动重传,在没有触发超时重传前,就已经触发发送方重传数据了。

        TCP为提高传输效率,使用了滑动窗口机制,什么是滑动窗口机制,我们在第4章节会讲到。使用滑动窗口时,发送方短时间内可发出了5条报文

  • 接收方收到seq1报文,返回ack2;
  • 接收方收到seq3报文,未收到seq2,还是返回ack2;
  • 接收方收到seq4和seq5报文,但还未收到seq2,最终还是返回ack2;
  • 发送方收到了3次重复的ack2,表明seq2丢失了,便立即重传丢失的seq2;
  • 接收方收到seq2报文,返回ack6。

        快速重传的工作方式是当发送方收到三次冗余的(不含第一次)重复的 ACK 报文时,在RTO生效前,立即重传丢失的报文段,这样就可以有效缩短重传时间。但这里面还存在效率的问题,如果发送方发出了6条或更多条报文,假设 seq2 和 seq3 都丢失了,发送方在收到3次冗余的ack2报文后,此时它首先能肯定的是seq2丢失了,但不确定seq2之后的数据有没有丢失,怎么办呢?只能先把seq2发出去再说,等收到后面的ack后再判读有没有其它数据丢失。假设当前通信网络环境不佳,发送方发送了很多条报文出去,丢包率为10%,发送方如果还是按照上面这种方式重传报文的话,其实效率也没提高多少。为了解决快重传的效率问题,于是就有了选择性确认SACK(Selective Acknowledgment),该参数位于TCP报头的Options,发送方可通过SACK值来判断哪部分数据丢失,有针对性地进行快重传,大大提高了重传效率。

2.3 SACK

        选择性确认(SACK,Selective Acknowledgment)用于数据重传机制,位于TCP报头的Options。接收方可通过SACK参数告知发送方我方收到了不连续的数据块(ack=200,SACK=300-400),发送方可根据此信息检查哪部分数据丢失(对方收到200字节数据,接收到了300-400段,说明200-299段丢失了)并重传丢失的数据。

        TCP三次握手过程中,双方会通过“SACK Permitted”来互相声明自己是否支持SACK,只有双方都支持SACK时,TCP才会使用SACK。Linux开启SACK的方法如下

#linux系统中可通过修改net.ipv4.tcp_sack来决定是否开启SACK,Linux 2.4后默认开启
[root@reader ~]# sysctl -a | grep net.ipv4.tcp_sack
net.ipv4.tcp_sack = 1
[root@reader ~]# find / -name *tcp_sack*
/proc/sys/net/ipv4/tcp_sack
[root@reader ~]# cat /proc/sys/net/ipv4/tcp_sack
1
[root@reader ~]# 

可以用echo或sysctl -w 来临时修改tcp_sack
也可以在系统配置文件 /etc/sysctl.conf 中,添加如下一行代码,永久修改 tcp_sack
net.ipv4.tcp_sack = <new_value>

2.4 D-SACK

        Duplicate SACK 又称D-SACK,主要是通过SACK来告知发送方有哪些数据被重复接收了。通过D-SACK可让发送方知道是我方发出的报文丢失还是对端返回的ACK报文丢失。如,发送方收到ack= 500,SACK=300-400这样的报文,意味着500之前的数据都接收到了,且重复收到了300-400的数据。

#linux系统中可通过修改net.ipv4.tcp_dsack来决定是否开启SACK,Linux 2.4后默认开启
[root@reader ~]# sysctl -a | grep net.ipv4.tcp_dsack
net.ipv4.tcp_dsack = 1
[root@reader ~]# find / -name *tcp_dsack*
/proc/sys/net/ipv4/tcp_dsack
[root@reader ~]# cat /proc/sys/net/ipv4/tcp_dsack
1
[root@reader ~]# 

可以用echo或sysctl -w 来临时修改tcp_dsack
也可以在系统配置文件 /etc/sysctl.conf 中,添加如下一行代码,永久修改 tcp_dsack
net.ipv4.tcp_dsack= <new_value>

3.连接管理机制

        通过三次握手建立连接,再通过四次挥手断开连接。

        参考文章 TCP三次握手、四次挥手及状态转换详解

效率机制

        TCP为了能最大限度的提高传输效率,分别从三方面对传输过程进行优化

  • 提高发送方的发送量(发送速率),如滑动窗口机制;
  • 提高接收方的接收能力(对方是否能承受大的数据量),如流量控制机制、延时应答机制;
  • 提高网络的转发能力(网络是否能转发大的数据量),如拥塞控制机制。

4.滑动窗口机制

4.1 什么是缓冲区?

  • TCP在操作系统中开辟的一块缓存空间,用于缓存将要发送和接收的数据;
  • TCP有两个缓冲区,分别是发送缓冲区接收缓冲区
  • 发送缓冲区和接收缓冲区都是环形队列
  • 应用层调用send函数将数据写入发送缓冲区,TCP从发送缓冲区获取数据并发送;
  • 网络层递交给TCP的数据最终被存放到接收缓冲区,应用层调用recv函数将数据从接收缓冲区读出。

4.2 什么是窗口?

        为解决因确认应答机制而导致的传输效率低下的问题,TCP引入了窗口概念。即使在RTT较长的情况下,也不会降低传输效率。

        窗口分“发送窗口”和“接收窗口”,首先它俩针对的缓冲区有所不同,发送窗口针对的是发送缓冲区,而接收窗口针对的是接收缓冲区。其次,发送方发送窗口的大小由接收方接收窗口的大小决定,但两者并不完全相等(因为有网络延迟),接收窗口大小约等于发送窗口大小。还需注意的是,窗口大小并不代表缓冲区的大小

        接收窗口(大小)就是我们通常讲的窗口(大小),对应TCP报头中的Window字段,表示接收端还剩多少接收缓冲区可用于接收数据。

        发送窗口(大小)指的是发送缓冲区中“已发送但未收到ACK确认”和“可以发送但还未发送”两块缓冲区的组成部分。这两部分的数据无需TCP确认就可直接推送给网络层。

        “已发送但未收到ACK确认”很好理解,就是已发送的报文在未等到确认应答ACK返回之前,必须保留在发送缓冲区中,如果在规定时间(RTO)内收到了ACK报文,就将数据从缓存区清除,否则重传报文。

        “可以发送但还未发送”指的是“可以发送但还没来得及发送,且总大小在接收方窗口大小范围之内”。

        注意:窗口是会动态变化的,可大可小,并不是下图中画的那样只有20字节;

        下面图中,如果32 ~ 45字节的数据状态不变,46 ~ 51字节的数据也已成功发送且未收到ACK确认,那么此时发送方的可用窗口就是0,在未收到新的ACK确认应答前无法继续发送数据。 

4.3 发送方的滑动窗口

        如下图,当32 ~ 36字节的数据收到ACK确认应答后,如果发送窗口大小不变,则滑动窗口往右移动5个字节,此时发送窗口就变成了由37 ~ 56字节组成的缓冲区了,后续就可以继续发送52 ~ 56字节之间的数据了。

4.4 发送方滑动窗口的四个组成部分

  • SND.WND:发送窗口大小(由接收窗口Window大小决定);
  • SND.UNA:是一个绝对指针,指向的是#2已发送但未收到ACK确认应答内容的第一个字节数据所对应的序列号;
  • SND.NXT:是一个绝对指针,指向的是#3可以发送但未发送内容的第一个字节数据所对应的序列号;
  • 是一个相对指针,SND.UNA + SND.WND,指向的是#4未发送且不能发送内容的第一个字节数据对应的序列号。

可用窗口大小 = SND.WND -(SND.NXT - SND.UNA)

4.5 接收方的滑动窗口(三部分)

  • RCV.WND:接收窗口大小,会赋值给Window并发送给发送方
  • RCV.NXT:是一个绝对指针,指向的是期望发送方下次发送来的数据的起始序列号,即ack值
  • 是一个相对指针,RCV.NXT + RCV.WND,指向的是#4未收到且不可以接收的第一个字节数据对应的序列号。

5.流量控制机制

        通过接收方的接收能力来控制发送方的发送数据量

6.延时应答机制

        接收方通过延时一小会,想要给发送方回复一个接收能力(更大的窗口大小)

7.捎带应答机制

8.拥塞控制机制

        通过不同的策略,不断的探测网络的转发能力,调整发送方的发送数据量

  • 慢启动
  • 拥塞避免
  • 快恢复

粘包处理

异常处理


参考文章:4.2 TCP 重传、滑动窗口、流量控制、拥塞控制 | 小林coding

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

多门店自助点餐+外卖二合一小程序系统源码:自助点餐+外卖配送 带完整搭建教程

互联网的普及和移动支付的便捷&#xff0c;餐饮行业也在经历着数字化转型。小编来给大家介绍一款多门店自助点餐外卖二合一小程序&#xff0c;带完整的搭建教程。 以下是部分代码示例&#xff1a; 系统特色功能一览&#xff1a; 1.多门店管理&#xff1a;支持一个平台管理多个…

华为OS与麒麟OS:华为自研操作系统的对决

导言 在移动操作系统领域&#xff0c;华为OS和麒麟OS代表了华为在自主研发方面的努力。本文将深入探讨这两个操作系统的特点、竞争关系以及它们在用户体验、生态系统建设等方面的差异。 1. 背景与起源 华为OS的诞生&#xff1a; 华为OS是华为公司为应对外部环境而自主…

【音视频 | AAC】AAC音频编码详解

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

网络基础【网线的制作、OSI七层模型、集线器、交换机介绍、路由器的配置】

目录 一.网线的制作 1.1.网线的标准 1.2.水晶头的做法 二.OSI七层模型、集线器、交换机介绍 集线器&#xff08;Hub&#xff09;&#xff1a; 交换机&#xff08;Switch&#xff09;&#xff1a; 三.路由器的配置 3.1.使用 3.2.常用的功能介绍 1、如何管理路由器 2、家…

SVN搭建指导

环境 centos 7.9 SVN安装方式一&#xff1a;yum 1.1 http服务 至今还没有搞定网页版&#xff0c;网页版需要搭建apache http服务。遇到如下问题&#xff1a; centos - svn: Could not open the requested SVN filesystem - Stack Overflow 在试了加777权限&#xff0c;加a…

Hal深入实战/perfetto-systrace实战/SurfaceFlinger合集-安卓framework开发实战开发

背景 hi&#xff0c;粉丝朋友们&#xff1a; 大家好&#xff01; 下面来介绍一下新的framework专题halperfettosurafceflinger&#xff0c;这个专题主要就是分为3大块&#xff0c;但是彼此直接又是相互关联的。 比如surfaceflingre模块深入分析需要用到hal相关的模块&#xff…

Git报错x509: certificate signed by unknown authority

下载报错&#xff1a; Error downloading object: model-00001-of-00008.safetensors (ed3ac49): Smudge error: Error downloading model-00001-of-00008.safetensors (ed3ac4983f682a999b0e4b6f072aad294c4fd9a7e968e90835ba5c4b466d3c7c): LFS: Get https://cdn-lfs.huggin…

百度侯震宇:AI原生与大模型将从三个层面重构云计算

12月20日&#xff0c;2023百度云智大会智算大会在北京举办&#xff0c;大会以「大模型重构云计算&#xff0c;Cloud for AI」为主题&#xff0c;深度聚焦大模型引发的云计算变革。 百度智能云表示&#xff0c;为满足大模型落地需求&#xff0c;正在基于「云智一体」战略重构…

〖大前端 - 基础入门三大核心之JS篇(58)〗- 面向对象案例

说明&#xff1a;该文属于 大前端全栈架构白宝书专栏&#xff0c;目前阶段免费&#xff0c;如需要项目实战或者是体系化资源&#xff0c;文末名片加V&#xff01;作者&#xff1a;哈哥撩编程&#xff0c;十余年工作经验, 从事过全栈研发、产品经理等工作&#xff0c;目前在公司…

饥荒Mod 开发(十七):手动保存和加载,无限重生

饥荒Mod 开发(十六)&#xff1a;五格装备栏 饥荒Mod 开发(十八)&#xff1a;Mod 添加配置选项 饥荒游戏会自动保存&#xff0c;本来是一个好的机制&#xff0c;但是当角色死亡的时候存档会被删除&#xff0c;又要从头开始&#xff0c;有可能一不小心玩了很久的档就直接给整没了…

C# NPOI导出dataset----Excel绘制Chart图表

仅限XLSX 2007以后版本&#xff08;2007之前版本不支持&#xff09; 1、判断文件夹是否存在&#xff0c;不存在则创建 //Application.StartupPath当前项目根目录 if (!Directory.Exists(Application.StartupPath "\Excel")) { …

用全志R128复刻自平衡赛车机器人,还实现了三种不同的操控方式

经常翻车的朋友们都知道&#xff0c;能在翻车后快速摆正车身的车才是好车。 就像动画《四驱兄弟》中展现的那样&#xff0c;在比赛中需要跟着赛车一起跑圈&#xff0c;而且赛车如果被撞翻还需要重新用手扶正&#xff0c;所浪费的时间非常影响比赛结果。 如果小豪和小烈可以拥有…

云原生扫盲篇

What 云原生加速了应用系统与基础设施资源之间的解耦,向下封装资源以便将复杂性下沉到基础设施层;向上支撑应用,让开发者更关注业务价值 云原生是一种构建和运行应用程序的方法,也是一套技术体系和方法论. Cloud 表示应用程序位于云中而不是传统的数据中心Native表示应用程序从…

基于STM32的DHT11温湿度传感器与LCD显示器的集成设计

在本文中&#xff0c;我们将详细介绍如何基于STM32微控制器实现DHT11温湿度传感器与LCD显示器的集成设计。我们将包括硬件连接、软件编程以及涉及的STM32库函数和相关知识。这个项目旨在帮助您理解如何使用STM32来读取DHT11温湿度传感器的数据&#xff0c;并将数据显示在LCD显示…

qt-C++笔记之使用QLabel和QPushButton实现一个bool状态的指示灯

qt-C笔记之使用QLabel和QPushButton实现一个bool状态的指示灯 code review! 文章目录 qt-C笔记之使用QLabel和QPushButton实现一个bool状态的指示灯1.QPushButton实现2.QLabel实现2.QLabel实现-对错符号 1.QPushButton实现 运行 代码 #include <QtWidgets>class Ind…

msvcp120.dll丢失的多种详细有效解决方法

在计算机使用过程中&#xff0c;我们可能会遇到一些错误提示&#xff0c;其中之一就是“msvcp120.dll丢失”。那么&#xff0c;msvcp120.dll到底是什么&#xff1f;为什么会出现丢失的情况&#xff1f;丢失后会对电脑产生什么影响&#xff1f;本文将为您详细解答这些问题&#…

计算机网络 运输层下 | TCP概述 可靠传输 流量控制 拥塞控制 连接管理

文章目录 3 运输层主要协议 TCP 概述3.1 TCP概述 特点3.2 TCP连接RSVP资源预留协议 4 TCP可靠传输4.1 可靠传输工作原理4.1.1 停止等待协议4.1.2 连续ARQ协议 4.2 TCP可靠通信的具体实现4.2.1 以字节为单位的滑动窗口4.2.2 超时重传时间的选择4.2.3 选择确认SACK 5 TCP的流量控…

MAC苹果笔记本电脑如何彻底清理垃圾文件软件?

苹果电脑以其流畅的操作系统和卓越的性能而备受用户喜爱。然而&#xff0c;随着时间的推移&#xff0c;系统可能会积累大量垃圾文件&#xff0c;影响性能。本文将介绍苹果电脑怎么清理垃圾文件的各种方法&#xff0c;以提升系统运行效率。 CleanMyMac X是一款专业的Mac清理软件…

C#中HttpWebRequest的用法

前言 HttpWebRequest是一个常用的类&#xff0c;用于发送和接收HTTP请求。在C#中使用HttpWebRequest可以实现各种功能&#xff0c;包括发送GET和POST请求、处理Cookie、设置请求头、添加参数等。本文将深入介绍HttpWebRequest的用法&#xff0c;并给出一些常见的示例。 目录 前…

01AVue入门(持续学习中)

1.使用AVue开发简单的前端页面直接简单到起飞,他是Element PlusVueVite开发的,不需要向元素的前端代码一样一个组件要传很多参数,他可以使用Json文本来控制我们要传入的数据结构来决定显示什么 //我使用的比较新,我们也可以使用cdn直接使用script标签直接引入 2.开发中遇到的坑…