当前位置: 首页 > news >正文

【网络面积篇】TCP断开连接(笔记)

目录

一. 四次挥手

(1)过程描述

(2)为什么是四次挥手?

二、相关问题

1. 第一次挥手丢失了,会发生什么?

2. 第二次挥手丢失了,会发生什么?

补充:close 函数 和 shutdown 函数的不同

3. 第三次挥手丢失了,会发生什么?

4. 第四次挥手丢失了,会发生什么?

5. 为什么需要 TIME_WAIT 状态?

(1)防止历史连接中的数据,被后面相同四元组的连接错误的接收

(2)保证「被动关闭连接」的一方,能被正确的关闭

6. 什么情况会出现三次挥手?

什么是 TCP 延迟确认机制?


一. 四次挥手

        双方 都可以 主动断开 连接,断开连接后 主机中的「资源」将被释放。

(1)过程描述

  • ① 客户端 打算 关闭连接,此时会发送一个 TCP 首部 FIN 标志位被置为 1 的报文,也即 FIN 报文,之后客户端进入 FIN_WAIT_1 状态。
  • ② 服务端收到该报文后,就向客户端发送 ACK 应答报文,接着服务端进入 CLOSE_WAIT 状态。
  • ③ 客户端 收到 服务端的 ACK 应答报文后,之后进入 FIN_WAIT_2 状态。
  • ④ 等待 服务端 处理完数据后,也向 客户端 发送 FIN 报文,之后 服务端 进入 LAST_ACK 状态。
  • ⑤ 客户端 收到 服务端的 FIN 报文后,回一个 ACK 应答报文,之后进入 TIME_WAIT 状态。
  • ⑥ 服务端收到了 ACK 应答报文后,就进入了 CLOSE 状态,至此 服务端已经 完成连接的关 闭。
  • ⑦ 客户端在经过 2MSL 一段时间后,自动进入 CLOSE 状态,至此 客户端 也完成 连接的关闭。

        这里 每个方向 都需要一个 FIN 和 一个 ACK,因此 通常被 称为 四次挥手。这里一点 需要注意是:主动关闭连接的,才有 TIME_WAIT 状态。

(2)为什么是四次挥手?

  • 关闭 连接时,客户端 向 服务端 发送 FIN 时,仅仅 表示客户端 不再发送 数据了 但是还能 接收数据。
  • 服务端 收到 客户端的 FIN 报文时,先回一个 ACK 应答报文,而 服务端 可能 还有 数据需要处理 和 发送,等 服务端 不再发送数据 时,才发送 FIN 报文 给客户端 来表示 同意现在 关闭连接。

        从 上面过程 可知,服务端 通常需要 等待完成 数据的 发送和处理,所以 服务端 的开发送,因此是 需要 四次挥手。ACK 和 FIN 一般 都会 分开发送,因此是 需要 四次挥手。

二、相关问题

1. 第一次挥手丢失了,会发生什么?

        当客户端(主动关闭方)调用 close 函数后,就会向服务端发送 FIN 报文,试图与服务端断开连接,此时客户端的连接进入到 FIN_WAIT_1状态。正常情况下,如果 能 及时 收到服务端(被动 关闭方)的 ACK,则会很快变为 FIN_WAIT_2 状态。

        如果 第一次挥手 丢失了,那么 客户端迟迟 收不到 被动方的 ACK 的话,也就会 触发 超时重传机制,重传 FIN 报文,重发次数由 tcp_orphan_retries 参数 控制。当客户端重传 FIN 报文的次数超过 tcp_orphan_retries 后,就不再发送 FIN 报文,则会在等待一段时间(时间为上一次超时时间的 2 倍),如果 还是没能 收到 第二次挥手,那么 直接进入到 close 状态

        举个例子,假设 tcp_orphan_retries 参数值 3,当 第一次挥手一直 丢失时,发生的 过程如下图:


        当客户端 超时重传 3 次 FIN 报文后,由于 tcp_orphan_retries 为 3,已 达到 最大重传 次数,于是 再等待一段时间(时间为 上一次 超时时间的 2 倍),如果 还是没能 收到 服务端的 第二次 挥手(ACK 报文),那么 客户端就会 断开连接。

2. 第二次挥手丢失了,会发生什么?

        当服务端 收到客户端的 第一次挥手后,就会先回一个 ACK 确认 报文,此时 服务端 的 连接进入到 CLOSE_WAIT 状态

        ACK 报文是不会重传的,所以 如果 服务端的 第二次挥手 丢失了,客户端 就会 触发超时重传机制,重传 FIN 报文,直到 收到 服务端的 第二次挥手,或者 达到最大的 重传次数。

        举个例子,假设 tcp_orphan_retries 参数值 2,当 第二次挥手 一直丢失 时,发生的 过程如下图:


        当客户端 超时重传 2 次 FIN 报文后,由于 tcp_orphan_retries 为 2,已达到 最大重传次数,于是再 等待一段时间(时间为 上一次 超时时间的 2 倍),如果 还是没能 收到 服务端 的 第二次挥手(ACK 报文),那么 客户端 就会 断开连接。

补充:close 函数 和 shutdown 函数的不同

        当 客户端 收到 第二次挥手,也就是 收到服务端 发送的 ACK 报文后,客户端 就会处于 FIN_WAIT_2 状态,在 这个状态 需要 等服务端 发送 第三次挥手,也就是 服务端的 FIN 报文。

        对于 close 函数关闭的 连接,由于 无法再 发送 和 接收数据,所以 FIN_WAIT_2 状态 不可以 持续太久,而 tcp_fin_timeout 控制了 这个状态下 连接的 持续时长,默认值是 60 秒。

        这 意味着 对于 调用 close 关闭的 连接,如果在 60 秒 后还 没有收到 FIN 报文,客户端(主动关闭方)的连接就会 直接关闭,如下图:

        如果 主动关闭方 使用 shutdown 函数 关闭连接,指定了 只关闭 发送方向,而 接收方向 并没有 关闭,那么 意味着 主动关闭方 还是 可以 接收数据的。此时,如果 主动关闭方 一直没 收到 第三次挥手,那么 主动关闭方的 连接 将会一直 处于 FIN_WAIT_2 状态(tcp_fin_timeout 无法控制 shutdown 关闭的连接)。如下图: 

3. 第三次挥手丢失了,会发生什么?

        当 服务端(被动关闭方)收到 客户端(主动关闭方)的 FIN 报文后,内核会 自动回复 ACK,同时 连接处于 CLOSE_WAIT 状态,顾名思义,它表示 等待 应用进程 调用 close 函数 关闭连接。此时,内核 是 没有权利 替代 进程 关闭连接,必须 由进程 主动 调用 close 函数来 触发 服务端 发送 FIN 报文。

        服务端 处于 CLOSE_WAIT 状态时,调用了 close 函数,内核 就会 发出 FIN 报文,同时 连接进入LAST_ACK 状态,等待 客户端 返回 ACK 来 确认连接 关闭。如果 迟迟 收不到这个 ACK,服务端就会重发 FIN 报文,重发次数 仍然 由 tcp_orphan_retries 参数 控制,这与 客户端 重发 FIN 报文的 重传次数 控制方式是 一样的。

        举个例子,假设 tcp_orphan_retries = 3,当 第三次挥手 一直丢失 时,发生的 过程如下图:


  • 当服务端 重传 第三次挥手 报文的 次数达到了 3 次 后,由于 tcp_orphan_retries 为 3,达到了 重传 最大次数,于是 再等待 一段时间(时间为 上一次 超时时间的 2 倍),如果 还是 没能 收到客户端的 第四次挥手(ACK 报文),那么 服务端 就会 断开连接。
  • 客户端 因为是 通过 close 函数 关闭连接的,处于 FIN_WAIT_2 状态是 有时长 限制的,如果tcp_fin_timeout 时间内 还是没能 收到服务端的 第三次挥手(FIN 报文),那么 客户端就会 断开连接。

4. 第四次挥手丢失了,会发生什么?

        当 客户端 收到服务端的 第三次挥手的 FIN 报文后,就会 回 ACK 报文,也就是 第四次挥手,此时 客户端 连接 进入 TIME_WAIT 状态。

        在 Linux 系统,TIME_WAIT 状态 会持续 2MSL 后才会 进入 关闭状态。然后,服务端(被动关闭方)没有收到 ACK 报文前,还是处于 LAST_ACK 状态。如果 第四次挥手 的 ACK 报文 没有 到达服务端,服务端 就会 重发 FIN 报文,重发次数 仍然由 tcp_orphan_retries 参数 控制。

        举个例子,假设tcp_orphan_retries 为 2,当 第四次挥手 一直丢失时,发生的过程如下:


  • 当 服务端 重传 第三次挥手 报文达到 2 时,由于 tcp_orphan_retries 为 2,达到了 最大重传次数,于是 再等待一段时间(时间为 上一次 超时时间的 2 倍),如果 还是没能 收到 客户端的 第四次挥手(ACK 报文),那么 服务端 就会 断开连接。
  • 客户端 在收到 第三次挥手后,就会进入 TIME_WAIT 状态,开启 时长为 2MSL 的定时器,如果途中 再次 收到 第三次挥手(FIN 报文)后,就会 重置定时器,当 等待 2MSL 时长后,客户端 就会断开连接。

5. 为什么需要 TIME_WAIT 状态?

(1)防止历史连接中的数据,被后面相同四元组的连接错误的接收

先来了解序列号(SEQ)和初始序列号(ISN):

  • 序列号,是 TCP 一个 头部字段,标识了 TCP 发送端 到 TCP 接收端的 数据流的 一个字节,因为TCP 是 面向字节流的 可靠协议,为了 保证消息的 顺序性和可靠性,TCP 为 每个传输方向上的 每个字节 都 赋予了一个 编号,以 便于 传输成功后 确认、丢失 后重传 以及在 接收端保证 不会乱序。序列号是一个 32 位的 无符号数,因此 在到达 4G 之后 再循环回到 0。
  • 初始 序列号在 TCP 建立连接的 时候,客户端和服务端 都会 各自生成一个 初始序列号,它是 基于 时钟生成的 一个 随机数,来 保证 每个连接 都拥有 不同的 初始序列号。初始化 序列号 可被视为 一个 32 位的 计数器,该 计数器 的数值 每 4 微秒 加 1,循环 一次需要 4.55 小时。

        序列号和初始化 序列号 并不是 无限递增的,会 发生 回绕为 初始值的 情况,这意味着 无法 根据序列号来 判断 新老数据。

        假设 TIME-WAIT 没有等待时间或时间过短,被延迟的数据包抵达后会发生什么呢?


  • 服务端 在 关闭连接 之前 发送的 SEQ =301 报文,被 网络 延迟了。
  • 接着,服务端 以相同的 四元组 重新打开了 新连接,前面 被延迟的 SEQ=301 这时 抵达了 客户端,而且 该数据报文的 序列号 刚好在 客户端 接收窗口内,因此 客户端会 正常接收 这个 数据报文,但是 这个数据报文是 上一个 连接残留下来 的,这样就 产生 数据错乱 等 严重的问题。

        为了 防止历史 连接中的 数据,被 后面 相同四元组的 连接错误的 接收,因此 TCP 设计了 TIME_WAIT 状态,状态 会 持续 2MSL 时长,这个 时间 足以让 两个方向上的 数据包都 被丢弃,使得 原来 连接的 数据包 在网络中 都 自然消失,再 出现的 数据包 一定都是 新建立 连接 所产生的。

(2)保证「被动关闭连接」的一方,能被正确的关闭

        TIME-WAIT 作用是 等待足够的时间 以确保 最后的 ACK 能让 被动关闭方 接收,从而 帮助其 正常关闭。

        如果 客户端(主动关闭方)最后一次 ACK 报文(第四次挥手)在 网络中 丢失了,那么 按照 TCP 可靠性原则,服务端(被动关闭方)会 重发 FIN 报文。

        假设 客户端 没有 TIME_WAIT 状态,而是在 发完 最后一次 回 ACK 报文就 直接进入 CLOSE 状态,如果该 ACK 报文 丢失了,服务端 则 重传的 FIN 报文,而这时 客户端 已经 进入到 关闭状态了,在 收到服务端 重传的 FIN 报文后,就会回 RST 报文。

        服务端 收到 这个 RST 并将其 解释为一个 错误(Connection reset by peer),这对于 一个 可靠的协议 来说 不是一个 优雅的 终止方式。为了 防止这种 情况出现,客户端 必须 等待足够长的 时间,确保 服务端 能够收到 ACK,如果 服务端 没有 收到 ACK,那么 就会触发 TCP 重传机制,服务端会 重新 发送一个 FIN,这样 一去一来 刚好 两个 MSL 的时间。

        客户端在 收到 服务端 重传的 FIN 报文时,TIME_WAIT 状态的 等待时间,会重置回 2MSL。

6. 什么情况会出现三次挥手?

        当 被动 关闭方(上图的 服务端)在 TCP 挥手过程中,「没有数据要发送」并且「开启了 TCP 延迟确认机制」,那么 第二 和 第三次 挥手 就会 合并传输,这样就 出现了 三次挥手。(TCP 延迟确认机 制 默认开启)


什么是 TCP 延迟确认机制?

        当 发送 没有携带 数据的 ACK,它的 网络效率 也是 很低的,因为 它也有 40 个字节的 IP 头 和TCP 头,但却 没有 携带 数据报文(浪费)。

为了解决 ACK 传输效率低 问题,所以就 衍生出了 TCP 延迟确认。TCP 延迟确认的策略:

  • 当 有响应数据 要发送 时,ACK 会 随着 响应数据 一起 立刻 发送给对方。
  • 当 没有 响应数据 要发送时,ACK 将会 延迟 一段时间,以 等待 是否有 响应 数据 可以一起 发送。
  • 如果 在 延迟等待 发送 ACK 期间,对方的 第二个 数据报文 又到达了,这时 就会 立刻发送 ACK。

相关文章:

【网络面积篇】TCP断开连接(笔记)

目录 一. 四次挥手 (1)过程描述 (2)为什么是四次挥手? 二、相关问题 1. 第一次挥手丢失了,会发生什么? 2. 第二次挥手丢失了,会发生什么? 补充:close …...

下跌多少才能涨回来?

文章目录 上涨下跌函数关系函数图形数学分析 上涨下跌函数关系 最近炒股很热,对于股票来说,有个很重要的参数涨跌幅,那么下跌多少才能涨回来?这个不需要太深的知识就可以计算出来,下跌和上涨不是等价的,下跌…...

【AAOS】【源码分析】CarSystemUI -- CarSystemBar

CarSystemBar不像Android手机那样固定的顶部“状态栏”和底部“导航栏”,而是将StatusBar和NavigationBar都统称为SystemBar,可以通过如下配置为每侧最多配置一个“系统栏”。 packages/apps/Car/SystemUI/res/values/config.xml<!-- Configure which system bars should …...

[供应链] 邀请招标

1.邀请招标定义 邀请招标(Invitation to Bid by Request) 也称为有限竞争性招标(limited Competitive Bidding)或选择性招标(Selected Bidding) 邀请招标的采购方式下&#xff0c;采购人(如政府机构、企业或其他组织)不是公开发布招标信息&#xff0c;而是根据供应商或承包商…...

VS2017+Qt5.12.9+CMake3.30.2编译VTK 9.2.0

一.准备工作 vs2017&#xff0c;QT&#xff0c;Cmake自行下载准备&#xff0c; VTK下载地址 1.官网下载 2.github下载 二.编译VTK源码 1.个人习惯创建以下目录&#xff0c;一个源码目录&#xff0c;Build为vs解决方案输出目录和编译输出以及中间生成文件目录 2.cmake基础…...

Java线程CPU占用过高如何排查?

使用ps命令查看java进程详细信息&#xff1a; ps aux | grep java使用top命令查看系统进程占用情况 top使用jstack命令导出Java进程的堆栈信息 jstack pid | grep tid -A 10 "java.lang.Thread.State" > gc.log找出占用cpu最高的线程id&#xff1a; top -Hp -d 1 …...

uniapp推送配置流程

Dcloud Dcloud注册账号 个推 了解即可 注册个推账号 ios配置流程 需配置含有推送的描述文件以及p8证书 配置推送证书 ios证书配置报技术错误&#xff08;参数错误&#xff09; TeamID-苹果开发者账号唯一的ID 安卓需配置多厂商 小米手机需要配置小米厂商 华为手机则需…...

qt QPicture详解

1、概述 QPicture类是Qt框架中的一个重要图形类&#xff0c;它主要用于记录和回放QPainter的绘图指令。这个类能够跨平台、无分辨率依赖地绘制图形&#xff0c;非常适合用于实现打印预览和图像操作等场景。QPicture可以将绘图操作序列化为一种独立于平台的格式&#xff0c;保存…...

ScheduledFuture Source Code Analysis

ScheduledFuture Overview is a delayed result-bearing action, 可以被cancel.通常是在ScheduledExecutorService里面schedule一个task, 然后ScheduledFuture是其task执行接受后的返回结果。 Code Analysis 继承于两个接口&#xff1a; extends Delayed, Future一些继承ch…...

【CSS】CSS 样式重置 (normalize.css 和 reset.css) 和通用样式配置

一般来说&#xff0c;每一个项目初始化阶段都需要样式重置和样式定制化。样式重置最常用的就是 normalize.css 和 reset.css 这两个文件。 他们的区别&#xff1a; Normalize.css更加注重保留有用的浏览器默认样式&#xff0c;仅修复浏览器之间的不一致性&#xff0c;适用于需…...

自动化机器学习(AutoML)详解

自动化机器学习&#xff08;AutoML&#xff09;详解 引言 在数据驱动的时代&#xff0c;将庞大的数据集转化为有价值的洞察和预测模型是众多组织的首要任务。然而&#xff0c;传统的机器学习流程复杂且耗时&#xff0c;包括数据预处理、特征选择、模型选择、调参以及模型评估…...

Linux: network:erspan0

文章目录 问题介绍生成时间:代码Linux引入后面NONE是怎么生成的问题 最近看到一个网卡是erspan0,不知道是做什么用的: # ip -d link show erspan0 7: erspan0@NONE: <BROADCAST,MULTICAST> mtu 1450 qdisc noop state DOWN mode DEFAULT group default qlen 10000...

第11课 计算思维

从二级考试开始&#xff0c;计算思维基本上以编程题的形式考察。为了避免一看就会&#xff0c;一写就废的情况&#xff0c;需要我们加强编程练习&#xff0c;把学到的知识&#xff0c;通过实战练习&#xff0c;变成自己的本领。 同一道题&#xff0c;一般会有多种解决方法&…...

ACL, ACL Workshop, ACL Findings 解释

ACL&#xff08;Annual Conference of the Association for Computational Linguistics&#xff09;是自然语言处理&#xff08;NLP&#xff09;领域的顶级会议之一&#xff0c;但确实有多个与ACL相关的会议和出版物&#xff0c;具体如下&#xff1a; ACL Main Conference&…...

《使用Gin框架构建分布式应用》阅读笔记:p272-p306

《用Gin框架构建分布式应用》学习第15天&#xff0c;p272-p306总结&#xff0c;总35页。 一、技术总结 1.TDD(test-driven development) 虽然经常看到TDD这个属于&#xff0c;从本人的工作经历看&#xff0c;实际开发中用得相对较少。 2.unitest(单元测试) go语言开发中&a…...

【搜索引擎】俄罗斯搜索引擎yandex

俄罗斯搜索引擎yandex 1997年&#xff0c;俄罗斯搜索引擎Yandex&#xff08;俄语意为&#xff1a;语言目录&#xff09;首次上线&#xff0c;已发展成为全球第四大搜索引擎和第二大非英语搜索引擎 https://yandex.com/...

加密源代码|html代码如何加密保护?3分钟学会4种源代码加密妙招,代码人必看

你是否曾担心过自己的源代码被轻易复制或篡改&#xff1f; 在这个开源和共享盛行的时代&#xff0c;如何加密源代码&#xff0c;成为了每个开发者不得不面对的问题。 古人云&#xff1a;“工欲善其事&#xff0c;必先利其器。”今天&#xff0c;我们就来探讨一下如何加密保护你…...

Jetson Orin NX平台自研载板 IMX477相机掉线问题调试记录

1. 前言 平台: NVIDIA Orin NX 硬件: 自研载板 相机: 3个IMX477树莓派HQ摄像头通过CSI接口连接 版本: L4T 35.4.1(我们也在35.5.0上测试了一些东西) 参数: 30fps,4032x3040 问题描述: 其中一个IMX477相机在录制过程中出现可变时间后退出 短则10秒,长则5小时,…...

spring-boot(整合mybatisplus、及常见注解)

介绍 在日常开发中单表的CRUD功能代码重复度很高,也没有什么难度。而这部分代码量往往比较大,开发起来比较费时。 目前企业中都会使用一些组件来简化或省略单表的CRUD开发工作。目前在国内使用较多的一个组件就是MybatisPlus. MyBatisPlus是针对于Mybatis框架的增强,即合…...

深度学习:yolov3的使用--建立模型

使用argparse模块来定义和解析命令行参数 创建一个ArgumentParser对象 parser argparse.ArgumentParser() 训练的轮数&#xff0c;每批图像的大小&#xff0c;更新模型参数之前累积梯度的次数,模型定义文件的路径。 parser.add_argument("--epochs", typeint, d…...

关于我、重生到500年前凭借C语言改变世界科技vlog.13——深入理解指针(3)

文章目录 1.字符指针变量2.数组指针变量3.函数指针变量4.函数指针数组5.二维数组传参本质6.拓展补充希望读者们多多三连支持小编会继续更新你们的鼓励就是我前进的动力&#xff01; 本章节接着学习常见的指针变量类型 1.字符指针变量 字符指针变量&#xff0c;顾名思义就是字…...

每日算法一练:剑指offer——数组篇(6)

1.点名 某班级 n 位同学的学号为 0 ~ n-1。点名结果记录于升序数组 records。假定仅有一位同学缺席&#xff0c;请返回他的学号。 示例 1: 输入: records [0,1,2,3,5] 输出: 4示例 2: 输入: records [0, 1, 2, 3, 4, 5, 6, 8] 输出: 7提示&#xff1a; 1 < records.le…...

【环境搭建】Apache ZooKeeper 3.8.4 Stable

软件环境 Ubuntu 20.04 、OpenJDK 11 OpenJDK 11&#xff08;如果已经安装&#xff0c;可以跳过这一步&#xff09; 安装OpenJDK 11&#xff1a; $ sudo apt-get update$ sudo apt-get install -y openjdk-11-jdk 设置 JAVA_HOME 环境变量&#xff1a; $ sudo gedit ~/.bash…...

算法练习——双指针

前言&#xff1a;大佬写博客给别人看&#xff0c;菜鸟写博客给自己看&#xff0c;我是菜鸟。 学前须知&#xff08;对自己&#xff09;&#xff1a;这里的指针不一定指地址&#xff01;也可能是数组下标。 1&#xff1a;移动零(双指针) 题目要求&#xff1a; 解题思路&#x…...

vue中el-table显示文本过长提示

1.el-table设置轻提示:show-overflow-tooltip“true“&#xff0c;改变轻提示宽度...

JS 字符串拼接并去重

1、includes 循环数组将某个字段拼接成新的字符串并去重&#xff08;数组里面包含的一个对象&#xff0c;或者其他都OK&#xff09; // 定义一个数组 let arr[.......] // 定义拼接的字符串 let a //循环数组将里面某个字段拼接在一起并去重 arr.forEach(item > {if(!a.in…...

opencv 图像预处理

图像预处理 ​ 在计算机视觉和图像处理领域&#xff0c;图像预处理是一个重要的步骤&#xff0c;它能够提高后续处理&#xff08;如特征提取、目标检测等&#xff09;的准确性和效率。OpenCV 提供了许多图像预处理的函数和方法&#xff0c;以下是一些常见的图像预处理操作&…...

SAP B1 功能模块字段介绍 - 价格清单(下)

目录 背景 五、业务伙伴的特殊价格 1. 单据逻辑功能 2. 部分字段解释 3. 操作流程 3.1 时间相关 3.2 数量相关 4. 实例 六、复制特殊价格到选择标准 1. 单据逻辑功能 2. 部分字段解释 七、全局更新特殊价格 ​编辑 1. 单据逻辑功能 2. 部分字段解释 八、价格更…...

传智杯 第六届-复赛-D

题目描述&#xff1a; 小红定义两个字符串同构&#xff0c;当且仅当对于i∈[1,n],b[i]−a[i]i∈[1,n],b[i]-a[i]i∈[1,n],b[i]−a[i]是定值。例如&#xff0c;"bacd"和"edfg"是同构的。 现在小红拿到了一个长度为n的字符串a&#xff0c;她想知道&a…...

Java - 数组实现大顶堆

题目描述 实现思路 要实现一个堆&#xff0c;我们首先要了解堆的概念。 堆是一种完全二叉树&#xff0c;分为大顶堆和小顶堆。 大顶堆&#xff1a;每个节点的值都大于或等于其子节点的值。 小顶堆&#xff1a;每个节点的值都小于或等于其子节点的值。 完全二叉树&#xff…...