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

news2024/11/23 19:19:19

序言

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

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

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

相关文章

【算法系列-链表】链表相交 环形链表II

【算法系列-链表】链表相交&环形链表 文章目录 【算法系列-链表】链表相交&环形链表1. 链表相交1.1 思路分析🎯1.2 解题过程🎬1.3 代码示例🌰 2. 环形链表II2.1 思路分析🎯2.2 代码示例🌰 1. 链表相交 【题目…

C/C++:内存管理

文章目录 前言一、内存分区1. 内存划分情况2. 最大内存计算 二、malloc/calloc/realloc 与 free1. malloc2. calloc3. realloc4. free5. 差异对比6. 失败处理 三、内存分配题目1. 题目2. 内存区域划分 四、C内存管理方式1. new 与 delete2. new/delete操作内置类型3. new和dele…

数据科学基础复习(简)

可视化、数据可视化 在狭义上,数据可视化是与信息可视化,科学可视化和可视分析学平行的概念,而在广义上数据可视化可以包含这3类可视化技术。 数据科学的主要任务 数据科学研究目的与任务 大数据及其运动规律的揭示从数据到智慧的转化数据…

【web安全】——命令执行漏洞/代码执行漏洞

1.命令执行漏洞 1.1漏洞原理 应用有时需要调用一些执行系统命令的函数,如PHP中的system、exec、shell_exec、passthru、popen、proc_popen等,当用户能控制这些函数的参数,并且开发人员对这个参数没有严格的过滤时就可以将恶意系统命令拼接到…

仿RabbitMQ实现消息队列服务端(二)

文章目录 ⽹络通信协议设计信道管理模块连接管理模块服务器模块实现 ⽹络通信协议设计 其中⽣产者和消费者都是客⼾端,它们都需要通过⽹络和BrokerServer进⾏通信。具体通信的过程我们使⽤Muduo库来实现,使⽤TCP作为通信的底层协议,同时在这个…

中级软件设计师:一文搞懂下午第二题——数据库设计

中级软件设计师:一文搞懂下午第二题——数据库设计 1. 数据库设计过程1.1 ER模型1.1.0 浅谈UML1.1.1 实体(Entity)1.1.2 联系1.1.3 联系类型1.1.4 实体间的联系模型 1.2 属性(Attribute)1.3 关系(Relations…

Python案例--动态奖金计算(个税计算)

在企业财务管理中,员工的奖金计算是一项关键任务,它直接关系到员工的积极性和忠诚度。一个合理的奖金制度能够激励员工更好地完成工作,提高企业的整体竞争力。本文将通过Python编程语言,详细探讨如何根据企业利润计算员工的奖金。…

ROS C++ : 使用ros::AsyncSpinner,实现多线程处理ROS消息

文章目录 1、原理说明1.1、ros::MultiThreadedSpinner1.2、ros::AsyncSpinner1.3、多线程原理1.3.1、 消息发布1.3.2、 消息订阅 2、ros::AsyncSpinner 示例13、ros::AsyncSpinner 示例24、使用 ros::AsyncSpinner, 多线程处理回调示例 1、原理说明 ROS提供了2中方…

风场可视化效果的实现,免费的预测数据获得方法

风场可视化是气象学、海洋学等领域中的重要研究工具,它能够直观地展示大气或海洋中的风速、风向等信息。通过风场的可视化,科研人员可以更好地理解气象数据的空间分布特征,分析风场的动力学特性。本文将介绍如何利用Python中的matplotlib、Ba…

git维护【.gitignore文件】

在工程下添加 .gitignore 文件【git忽略文件】 *.class .idea *.iml *.jar /*/target/

如何通过几个简单步骤创建博客

搭建博客不仅可以表达自我和分享知识,还可以成为一种潜在的收入来源。如果你也对搭建博客感兴趣,下面的几个步骤将帮助你轻松入门。 一、选择一个主题 确定你的兴趣点:首先,你需要选择一个你感兴趣且擅长的领域。你悉的领域既能激…

基于SpringBoot+Vue的蛋糕甜品商城系统

系统展示 用户前台界面 管理员后台界面 系统背景 随着互联网技术的飞速发展,电子商务已经深入人们的日常生活,各行各业都在积极拥抱数字化转型。蛋糕甜品行业也不例外,传统的销售模式已经无法满足消费者日益增长的多样化、便捷化需求。因此&a…

每日学习一个数据结构-树

文章目录 树的相关概念一、树的定义二、树的基本术语三、树的分类四、特殊类型的树五、树的遍历六、树的应用场景 树的遍历一、前序遍历二、中序遍历三、后序遍历使用java代码实现遍历总结 树的相关概念 树是一种重要的非线性数据结构,在计算机科学中有着广泛的应用…

Pikachu-File Inclusion-远程文件包含

远程文件包含漏洞 是指能够包含远程服务器上的文件并执行。由于远程服务器的文件是我们可控的,因此漏洞一旦存在,危害性会很大。但远程文件包含漏洞的利用条件较为苛刻;因此,在web应用系统的功能设计上尽量不要让前端用户直接传变…

【GT240X】【04】你必须知道的 50 多个 Linux 命令

文章目录 一、介绍二、五十个linux命令一览表三、50个命令详解四、结论 你必须知道的 50 多个 Linux 命令 一、介绍 你经常使用 Linux 命令?今天,我们将介绍 50 多个你必须知道的 Linux 命令。下面列出的命令是一些最有用和最常用的 Linux 命令&#x…

jmeter学习(5)定时

Jmeter之定时器_jmeter定时器-CSDN博客 Jmeter(十三) - 从入门到精通 - JMeter定时器 - 上篇(详解教程)-腾讯云开发者社区-腾讯云 (tencent.com) 定时器是在每个sampler之前执行的,无论定时器位置在sampler之前还是子节点下面当执行一个sam…

TypeScript 算法手册 【基数排序】

文章目录 1. 基数排序简介1.1 基数排序定义1.2 基数排序特点 2. 基数排序步骤过程拆解2.1 找出数组中的最大值2.2 从最低位开始,对每一位进行计数排序2.3 对某一位数进行计数排序2.4 将排序结果复制回原数组 3. 基数排序的优化3.1 处理负数3.2 字符串排序案例代码和…

Go语言实现随机森林 (Random Forest)算法

在 Go 语言中实现随机森林(Random Forest)算法通常涉及以下几个步骤: 数据准备:将数据集分为训练集和测试集,确保数据格式适合算法使用。 决策树的构建:随机森林是由多个决策树构成的,首先需要…

MySQL 实验1:Windows 环境下 MySQL5.5 安装与配置

MySQL 实验1:Windows 环境下 MySQL5.5 安装与配置 目录 MySQL 实验1:Windows 环境下 MySQL5.5 安装与配置一、MySQL 软件的下载二、安装 MySQL三、配置 MySQL1、配置环境变量2、安装并启动 MySQL 服务3、设置 MySQL 字符集4、为 root 用户设置登录密码 一…

使用前端三剑客实现一个备忘录

一,界面介绍 这个备忘录的界面效果如下: 可以实现任务的增删,并且在任务被勾选后会被放到已完成的下面。 示例: (1),增加一个任务 (2),勾选任务 &#xff…