TCP --- 确认应答机制以及三次握手四次挥手

序言

 在前一篇文章中,我们介绍了 UDP协议 (点击查看)👈,该协议给我们的感觉就两个字 — 简单,只是将我们的数据进行简单的添加报头然后发送。当然使用起来虽然简单,但是否能送到目的地,那就要看网络的状态了以及一些随机成分了。
 今天介绍的 TCP 比起前者的原理要复杂很多,但是正是因为这个缜密的设计才能让我们的通信更加的稳定!


TCP 协议段格

 光是看该协议段格式的设计就比 UDP 丰富许多:
在这里插入图片描述

 字段很多,我们在这里只是简单的介绍不过多的阐述,在后面讲述功能时会将对应的字段进行详细的介绍。
 头两个字段,源端口,目的端口 也就是表示数据是从哪个进程来,到哪个进程去,这在 UDP 中出现过。现在介绍我们之前没见过的:

  • 序列号TCP 会将数据较大的数据包进行分段处理后再发送,序号用于标识数据段的顺序,确保数据按顺序到达接收方

  • 确认应答号:用于确认已接收到的数据,确保数据的可靠传输。确认号的值表示接收方期望收到的下一个数据段的序号。

  • 首部长度:表示 TCP 报头的长度,单位是 4 字节。这代表 TCP 长度的最大值为 60 字节。

  • 窗口大小:通过滑动窗口来控制流量,后面会详细介绍。

  • 6 个标志位
    URG: 紧急指针是否有效
    ACK: 应答标记位
    PSH: 提示接收端应用程序立刻从 TCP 缓冲区把数据读走
    RST: 对方要求重新建立连接
    SYN: 请求建立连接
    FIN: 断开连接

  • 校验和,紧急指针,选项:本篇文章不提及。


确认应答机制

1. 基本原理

 灵感来源于生活!举个简单的例子:你正在厨房里做饭,你的孩子正在房间里愉快的开黑。饭做好了,你朝着房间说:吃饭了!吃饭了!你的孩子收到了,说了一声:好的!我来啦!但是如果房间里没有任何的回应呢?那你肯定再次重复,直到你的孩子听见了,对你有了答复。
 所以怎么保证对方收到了你的消息呢?给你应答!确认应答机制就是这样:当接收方成功接收到发送方发送的数据段后,它会向发送方发送一个 ACK 报文,以确认该数据段已被成功接收。

2. 基本流程

 发送方将要发送的数据 每个字节的数据都进行了编号.即为序列号
在这里插入图片描述

然后,发送方将这些数据段依次发送给接收方。

 就比如,发送端现在一共将数据分成了三段,每一段的序列号分别是:1000,2000,3000。接收端收到序列号为 1000 的数据包时,会发送一个应答报文(ACK 置 1),表示收到该段数据。那么,该确认应答号应该是 1000 咯。

 不是的!确认应答号 = 接受的序列号 + 1,表示 收到该确认序列号之前的数据,期望的收到的下一个数据段的开始。 为什么要这样设计呢?允许少量的应答报文丢失。如果我们使用的第一种方式,那么我们必须保证收到该序列号报文对应的 ACK 报文,没收到就认为是丢失,需要补发!但是我们采取第二种方式,比如现在一共发了六个数据包,就算前面的丢失了,但是只要返回了第六个的应答报文,那么就意味着六个都到了!

重传机制

 在网络中传输数据,免不了会遇到数据丢失的情况,那么 TCP 遭遇这种情况时,是怎么处理的呢?

1. 超时重传

 主机 A 向 主机B 发送了一段数据,但是 A 迟迟没有接收到来自 B 的应答报文。会是什么原因呢?

  • 主机 A 的发送的数据包丢失了或阻塞了
  • 主机 B 的应答报文丢失了或阻塞了

主机 A 肯定不知道原因是什么,他只会补发数据直到收到应答报文!那么什么时候 A 会去补发数据呢:
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/766f33111e8541f28cb12a7ba640e796.p

 首先这个时间间隔肯定不是固定的!因为网络情况是波动的,当网络延迟高的时候,时间肯定短一点,及时的去补发数据;当网络延迟低的时候,时间肯定长一点,避免频繁发送重复的包。

 具体的步骤是,起始的时间间隔为 500ms,如果重发一次之后,仍然得不到应答,等待 2*500ms 后再进行重传。如果仍然得不到应答, 等待 4*500ms 进行重传。类推,累计到一定的重传次数,TCP 认为网络或者对端主机出现异常,强制关闭连接。

2. 快重传

 比如现在我们一共有 10 个数据段,序号分别是 1000,2000,… ,10000, 现在发送端将数据全部发送,除了 2000 都到了接收端,那么接收端是如何返回应答报文的呢:
在这里插入图片描述
 为什么返回的应答报文的确认应答号都是 1001 呢?在之前说了,确认应答号代表该号数之前的数据已经被接受! 就拿序列号为 5000 的来说,该序列号对应的报文确实已经被收到了,但是他之前的报文还缺一个 2000(1001 ~ 2000),所以只能是返回 1001。

 当发送端接收到 连续的3个重复确认,它会立即重新发送丢失的数据段,而不需要等待超时时间到期。

TCP 的确认应答机制通过发送 ACK报文、引入重传机制和序列号管理等方式,确保了数据的可靠传输。这一机制在 TCP 协议中起着至关重要的作用,为网络通信的可靠性和稳定性提供了有力保障。


连接管理

 在这里的连接管理,实际上就是我们常听到的三次握手建立连接,四次挥手断开连接的过程。

1. 三次握手

 首先,我们来分析一下三次握手的过程:
在这里插入图片描述

  1. 客户端发送SYN 报文,想要和服务端建立连接,进入 SYN_SENT 状态
  2. 服务端接收到请求后表示同意,并且也表示想要建立连接,进入 SYN_RCVD 状态
  3. 客户端收到报文后,回应最后一个 ACK 报文,进入 ESTABLISHED 状态
  4. 服务器收到应答后,也进入 ESTABLISHED 状态

在这里我们首先解决几个前面没有介绍的知识点:

  • 标记位报文:在这里我们提到发送 SYN报文 (表示建立连接),但是 SYN 只是一个标记位呀?没关系的,我们只需要将该标记位置 1
    ,数据字段不填就是了。常见的还有:ACK报文(表示应答对应的数据),FIN(请求断开连接)
  • 捎带标记位:比如当 A 向主机 B 发送数据后,B 肯定需要发送应答报文,但是此时恰巧 B 也有向 A 发送的数据,那么就可以将该数据和应答合并发送(两者并不会冲突,因为应答只需要将标记位 ACK 置 1 即可),不需要单独发送一个仅包含
    ACK 的包,从而 减少网络上的数据包数量

好的了解三次握手建立连接的步骤后,我们提出以下问题:

  • 为什么是三次,不是四次,五次?
  • 如果第一次握手请求丢失会怎么样?
  • 如果第二次握手请求丢失会怎么样?
  • 如果第三次握手请求丢失会怎么样?

问题只会帮助我们更好的理解知识,现在我们一个一个的来解释一下:

问题一

  • 保证双方具有发送和接受信息的能力:在这三次握手中,发送端发送了一次数据(最开始的 SYN报文),接受了一次数据(ACK + SYN);接收端接受了一次数据(最开始的 SYN报文),发送了一次数据(ACK + SYN)。三次握手以最小的成本保证双方具有接收和发送的能力! 你四次(如果将中间的捎带应答分开,分两次发,也就是四次应答!)五次都行,但是没必要!
  • 初始化并同步序列号:接收端和发送端根据序列号来标识每个传输的数据包,确保数据的顺序性和完整性。你想一下,如果你在第一次发了一个数据包但是在网络上阻塞了,数据迟迟没到,你断开了连接;过了一会你重新建立连接,再次发送数据,好巧不巧第一次在网络上阻塞的数据也到了接收端,如果接收端接受了那么肯定数据就错乱了!为了避免这种情况,每次建立连接时,双方都会生成一个新的初始序列号,这是为了确保通信的可靠性和安全性
  • 避免历史连接:在这里我们引入一个实际的场景:
    在这里插入图片描述
    原来存在一个历史的连接请求阻塞在网络中,现在客户端发起一个新的连接请求,但是历史的请求也到达了服务端。如果没有中间那次服务端的确认,那么在两次握手后服务端就成功进入 ESTABLISHED 状态。如果服务端向客户端发送相应的数据,这不是妥妥浪费资源吗?所以,我们需要一个中间状态来确认对方的身份,阻止历史连接造成资源的浪费!

问题二
 如果第一次链接请求都丢失了,那么则会触发前面说到的 超时重传

问题三

  • 对于客户端来说,我没有收到你的 ACK ,那么是不是我的请求没有送到呢?于是会触发 超时重传
  • 对于服务端来说,我的信息都发出这么久了咋还不回我,触发 超时重传

两者都会触发 超时重传 ,因为在网络上确认对方收到自己信息的唯一方式就是收到相应的应答,没收到应答,我就认为你没有收到我的信息!

问题四
 因为这个第三次握手的 ACK 是对第二次握手的 SYN 的确认报文,所以当第三次握手丢失了,如果服务端那一方迟迟收不到这个确认报文,就会触发超时重传机制,重传 SYN-ACK 报文,直到收到第三次握手或者达到最大重传次数。

 这就是三次握手建立连接的过程。

2. 四次挥手

 老样子,先认识到四次挥手的过程是什么样:
在这里插入图片描述

  1. 客户端发送 FIN 报文请求断开连接,进入 FIN_WAIT_1 状态
  2. 服务端收到请求,返回 ACK 应答报文,进入 CLOSED_WAIT 状态,客户端进入 FIN_WAIT_2 状态
  3. 服务端发送 FIN 报文请求断开连接,进入 LAST_ACK 状态,客户端进入 TIME_WAIT 状态
  4. 服务端收到 ACK 后断开,客户端一段时间后断开

了解到四次挥手的过程后,我们提出以下问题:

  • 为什么是四次挥手?为什么不在第一次时就直接断开?
  • 为什么客户端在最后需要等待一段时间?

问题一
 引入生活场景。你和你的女朋友(or 男朋友)吵架了,你的女朋友说,我不想聊了,我要断开连接!好的,现在她不说话了,你有两个选择:

  • A:不聊就不聊,我也断开连接!
  • B:向她解释,千万不能断开连接!

通常情况下,咋们还是选择第二种。你的女朋友确实不会再发送消息给你了,但是不代表她不能听呀!她的话说完了,你的话也许还有呢?

现在回到网络上,客户端断开代表他的数据已经发送完了但是还能接收消息,而服务端可能还存在着需要处理的数据需要发送给客户端。当服务端的数据也已经处理完了,就会发送 FIN 报文同意断开连接。

所以说断开连接需要双方的同意,需要四次挥手!那有没有可能,服务端确实没有什么数据需要处理的情况呢?那肯定有,所以此时我们中间的 ACKFIN 就可以捎带应答的方式发送,四次挥手变成三次回收!

问题二

  • 保证被动的一方正常的断开:在这里不是主动断开的一方统称为被动的一方。四次挥手的最后客户端向服务端发送一个 ACK 应答报文表示收到了,服务端这才关闭连接。但是如果该报文没有正常送达呢?那服务器肯定要补发 FIN 数据包嘛,如果此时客户端早就断线了,在收到服务端重传的 FIN 报文后,就会回 RST 报文,这并不是一个好的结束方式。
  • 处理历史遗留数据:在这里大家记住一个结论:序列号和初始化序列号并不是无限递增的,无法根据序列号来判断新老数据。会发生回绕为初始值的情况。 所以为了避免本次连接在网络中被延迟的数据被下一次新的连接所接收,所以我们需要一个时间来接受这些数据并丢弃!MSL 是报文在网络中的最大生存时间,2MAL 足以处理这些被延迟的报文了。

 这就是四次挥手断开连接的过程。


总结

 在这一篇文章中,我们介绍了 TCP 的协议段格式,以及保证其可靠传输的确认应答机制,重传机制,着重介绍了三次握手建立连接,四次挥手断开连接的过程,希望大家有所收获!

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

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

相关文章

深度学习——线性神经网络(一、线性回归)

目录 一、线性回归1.1 线性回归的基本元素1.1.1 术语介绍1.1.2 线性模型1.1.3 损失函数1.1.4 解析解1.1.5 随机梯度下降1.1.6 模型预测 1.2 正态分布与平方损失 因为线性神经网络篇幅比较长,就拆成几篇博客分开发布。目录序号保持连贯性。 一、线性回归 回归&#x…

[Linux] Linux 的进程如何调度——Linux的 O(1)进程调度算法

标题:[Linux] Linux 的进程如何调度——优先级与进程调度 个人主页水墨不写bug 目录 一、前言 二、将要出现的概念 1.进程调度队列 2.位图 3.进程的优先级 三、Linux进程的调度过程 1.活动队列(*active指向的队列) 2.过期队列&#…

LeetCode[中等] 763. 划分字母区间

给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。 注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s 。 返回一个表示每个字符串片段的长度的列表。 思路 贪心…

Centos 7.9 Kubeadm安装k8s1.20.11

一、环境 主机用途192.168.76.140k8s-master1192.168.76.141k8s-node1 二、设置yum源 由于系统已经关闭,可以用centos9尝试 cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak vi /etc/yum.repos.d/CentOS-Base.repo# 使用阿里云的y…

【动态规划-分组背包】【hard】力扣2218. 从栈中取出 K 个硬币的最大面值和

一张桌子上总共有 n 个硬币 栈 。每个栈有 正整数 个带面值的硬币。 每一次操作中,你可以从任意一个栈的 顶部 取出 1 个硬币,从栈中移除它,并放入你的钱包里。 给你一个列表 piles ,其中 piles[i] 是一个整数数组,分…

FOC电机驱动开发踩坑记录

关键技术 SVPWM电机磁场控制电流采样park变换和Clark变换滑膜观测器(无感FOC) SVPWM电机磁场控制 SVPWM主要思想是通过精确的对UVW三相电流的分时控制,来控制转子的合成力矩,达到目标方向,常用的是6分区的设计&…

浅谈汽车智能座舱如何实现多通道音频

一、引言 随着汽车智能座舱的功能迭代发展,传统的 4 通道、6 通道、8 通道等音响系统难以在满足驾驶场景的需求,未来对于智能座舱音频质量和通道数会越来越高。接下来本文将浅析目前智能座舱如何实现音频功放,以及如何实现多路音频功放方案。…

C语言+单片机

今天内容有点水哈哈&#xff08;忙着练焊铁技术了嘻嘻&#xff09; C语言 简单学习了while语言以及其与for语言的区别和适用方法 .循环结构&#xff1a; 初始化语句条件判断句条件控制句 for语句 for(int1;i<100;i){执行条件} for (int i 1; i < 100; i) {printf(&quo…

leetcode每日一题day22(24.10.2)——准时到达的列车最小时速

思路&#xff1a;这种在有约束条件情况下&#xff0c;求最值或最符合要求的情况&#xff0c;首先是很容易想到&#xff0c;从时速为1开始往后找找到满足条件就输出&#xff0c;但这无疑工程量很大&#xff0c;每种可能的速度都要对列车数组进行遍历&#xff0c; 时间复杂度为C…

Stable Diffusion绘画 | 来训练属于自己的模型:LoRA模型验收

我们每次训练出来的模型&#xff0c;一般都会生成 20-30 个&#xff0c;至于哪个模型符合要求&#xff0c;较为理想呢&#xff1f; 接下来需要对每个 LoRA模型 进行逐一对比测试。 为了测试模型的泛化性&#xff0c;可选择使用一些较为特殊的提示词&#xff0c;看看各个模型对…

828华为云征文 | 云服务器Flexus X实例:向量数据库 pgvector 部署,实现向量检索

目录 一、什么是向量数据库 pgvector &#xff1f; 二、pgvector 部署 2.1 安装 Docker 2.2 拉取镜像 2.3 添加规则 三、pgvector 运行 3.1 运行 pgvector 3.2 连接 pgvector 3.3 pgvector 常见操作 四、总结 本篇文章通过 云服务器Flexus X实例 部署向量数据库 pgve…

安卓13默认使用大鼠标 与配置分析 andriod13默认使用大鼠标 与配置分析

总纲 android13 rom 开发总纲说明 文章目录 1.前言2.问题分析3.代码分析4.代码修改5.彩蛋1.前言 android13里面的鼠标貌似比以前版本的鼠标小了,有些客户想要把这个鼠标改大。这个功能,android有现成的,就在这里,设置 =》无障碍 =》色彩和动画 =》 大号鼠标指针。 我们通过…

Spring注解系列 - @Autowired注解

文章目录 使用总结注入原理Autowired 注入过程InjectionMetadataInjectedElement依赖注入查找过程findAutowireCandidates 缓存注入信息 Resource 注解 使用总结 Autowired注解可以自动将所需的依赖对象注入到类的属性、构造方法或方法中&#xff0c;从而减少手动注入依赖的代…

ubuntu 设置静态IP

一、 ip addresssudo nano /etc/netplan/50-cloud-init.yaml 修改前&#xff1a; 修改后&#xff1a; # This file is generated from information provided by the datasource. Changes # to it will not persist across an instance reboot. To disable cloud-inits # ne…

【重学 MySQL】五十、添加数据

【重学 MySQL】五十、添加数据 使用INSERT INTO语句添加数据基本语法示例插入多行数据注意事项 使用LOAD DATA INFILE语句批量添加数据其他插入数据的方式注意事项 在MySQL中&#xff0c;添加数据是数据库操作中的基本操作之一。 使用INSERT INTO语句添加数据 使用 INSERT IN…

单链表的增删改查(数据结构)

之前我们学习了动态顺序表&#xff0c;今天我们来讲一讲单链表是如何进行增删改查的 一、单链表 1.1、单链表概念 概念&#xff1a;链表是⼀种物理存储结构上⾮连续、⾮顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接次序实现的。 1.2、链表与顺序表的…

python的几个基本数据类型及其相关操作(字符串str,元组tuple,列表list,字典dict)

一、str及其相关操作 1、字符串的基本方法 字符串的索引、获取字符串长度、利用index获取索引位置&#xff0c;统计某字符在字符串中出现的次数。用法如下方代码。 python的变量在创建时不需要声明其数据类型&#xff0c;他会自动识别变量后的数据类型&#xff0c;所以创建一…

(undone) 阅读 MapReduce 论文笔记

参考&#xff1a;https://pdos.csail.mit.edu/6.824/papers/mapreduce.pdf 摘要&#xff1a;简单介绍了 MapReduce 是在大型分布式系统上工作的 Introduction 的内容总结&#xff1a; 1.介绍背景&#xff1a;为什么我们需要分布式系统&#xff1f;MapReduce 的意义是哪些 2.简…

运动耳机哪个牌子的好?5大质量不凡的运动耳机测评力荐!

在快节奏的生活中&#xff0c;无论是晨跑、健身还是户外探险&#xff0c;音乐都成了许多人不可或缺的陪伴。运动耳机&#xff0c;作为一种专为运动场景设计的音频设备&#xff0c;旨在提供高质量音频体验的同时&#xff0c;保证佩戴的舒适度和运动的安全性。 &#xff08;上图为…

YOLOv11改进 | 主干篇 | YOLOv11引入MobileNetV4

1. MobileNetV4介绍 1.1 摘要&#xff1a; 我们推出了最新一代的 MobileNet&#xff0c;称为 MobileNetV4 (MNv4)&#xff0c;具有适用于移动设备的通用高效架构设计。 在其核心&#xff0c;我们引入了通用倒瓶颈&#xff08;UIB&#xff09;搜索块&#xff0c;这是一种统一且…