【windows|014】TCP协议详解

news2024/11/15 3:40:47

🍁博主简介

🏅云计算领域优质创作者

🏅2022年CSDN新星计划python赛道第一名

🏅2022年CSDN原力计划优质作者 ​

🏅阿里云ACE认证高级工程师 ​

🏅阿里云开发者社区专家博主

💊交流社区:CSDN云计算交流社区欢迎您的加入!

目录

1、TCP报文格式及参数含义

2、TCP协议的基本特点

3、三次握手(TCP协议的连接建立)

4、为什么三次握手?而不是二次、四次握手?

5、TCP三次握手中的异常情况

5.1 异常一:第一次握手丢了

5.2 异常二:第二次握手丢了

5.3 异常三:第三次握手丢了

5.4 异常四:SYN 攻击与避免

6、四次挥手(TCP协议的连接释放)

7、TCP四次挥手中的异常情况

7.1 第一次挥手丢了

7.2 第二次挥手丢了

7.3 第三次挥手丢了

7.4 第四次挥手丢了

8、抓包分析TCP协议

9、TCP协议的应用场景


1、TCP报文格式及参数含义

TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议。它工作在OSI模型的第四层,即传输层,为用户提供可靠的、有序的和无差错的数据传输服务。TCP协议与UDP协议是传输层的两大主要协议,但两者在设计上有明显的不同:TCP提供的是可靠的数据传输服务,而UDP则更注重传输的速度和效率

TCP 把连接作为最基本的对象,每一条 TCP 连接都有两个端点,这种端点我们叫作套接字(socket),它的定义为端口号拼接到 IP 地址即构成了套接字,例如,若 IP 地址为 192.168.10.11 而端口号为 80,那么得到的套接字为192.168.10.11:80。IP 协议虽然能把数据报文送到目的主机,但是并没有交付给主机的具体应用进程。而端到端的通信才是应用进程之间的通信。

TCP 报文是 TCP 层传输的数据单元,也叫报文段。TCP 报文的格式如下图所示:

每个参数的含义:

  • 来源端口号(16位):识别发送连接端口。

  • 目的端口号(16位):识别接收连接端口。

  • 序列号(seq,32位):用来解决网络乱序问题。

    如果含有同步化标志(SYN),则此为最初的序列号(ISN),第一个数据字节的序列号为 ISN + 1;如果没有同步化标志(SYN),则此为第一个数据比特的序列号。

  • 确认号(ack,32位):期望收到的数据的开始序列号,发送端收到这个确认应答以后可以认为在这个序号以前的数据都已经被正常接收。用来解决丢包的问题。

  • 数据偏移(4位):以4字节为单位计算出的数据段开始地址的偏移值。相对于TCP头开始位置,没有选项时该值为5。

  • 保留(3位):须置0

  • 标志符(9位)

  • NS:ECN-nonce。ECN显式拥塞通知(Explicit Congestion Notification)是对TCP的扩展,定义于 RFC 3540 (2003)。ECN允许拥塞控制的端对端通知而避免丢包。ECN为一项可选功能,如果底层网络设施支持,则可能被启用ECN的两个端点使用。在ECN成功协商的情况下,ECN感知路由器可以在IP头中设置一个标记来代替丢弃数据包,以标明阻塞即将发生。数据包的接收端回应发送端的表示,降低其传输速率,就如同在往常中检测到包丢失那样。

  • CWR:Congestion Window Reduced,定义于 RFC 3168(2001)。

  • ECE:ECN-Echo有两种意思,取决于SYN标志的值,定义于 RFC 3168(2001)。

  • URG:为1表示高优先级数据包,紧急指针字段有效。

  • ACK:为1表示确认号字段有效。

  • PSH:为1表示是带有PUSH标志的数据,指示接收方应该尽快将这个报文段交给应用层而不用等待缓冲区装满。

  • RST:为1表示出现严重差错。可能需要重新创建TCP连接。还可以用于拒绝非法的报文段和拒绝连接请求。

  • SYN:为1表示这是连接请求或是连接接受请求,用于创建连接和使顺序号同步。

  • FIN:为1表示发送方没有数据要传输了,要求释放连接。

  • 窗口大小(WIN,16位):表示从确认号开始,本报文的发送方可以接收的字节数,即接收窗口大小。用于流量控制。

  • 校验和(Checksum,16位):对整个的TCP报文段,包括TCP头部和TCP数据,以16位字进行计算所得。这是一个强制性的字段。

  • 紧急指针(16位):本报文段中的紧急数据的最后一个字节的序号。

  • 选项(最多40字节):每个选项的开始是1字节的kind字段,说明选项的类型。

    • 0:选项表结束(1字节)

    • 1:无操作(1字节)用于选项字段之间的字边界对齐。

    • 2:最大报文段长度(4字节,Maximum Segment Size,MSS)通常在创建连接而设置SYN标志的数据包中指明这个选项,指明本端所能接收的最大长度的报文段。通常将MSS设置为(MTU-40)字节,携带TCP报文段的IP数据报的长度就不会超过MTU(MTU最大长度为1518字节,最短为64字节),从而避免本机发生IP分片。只能出现在同步报文段中,否则将被忽略。

    • 3:窗口扩大因子(3字节,wscale),取值0-14。用来把TCP的窗口的值左移的位数,使窗口值乘倍。只能出现在同步报文段中,否则将被忽略。这是因为现在的TCP接收数据缓冲区(接收窗口)的长度通常大于65535字节。

    • 4:sackOK,发送端支持并同意使用 SACK 选项。

    • 5:SACK 实际工作的选项。

    • 8:时间戳(10字节,TCP Timestamps Option,TSopt),

      发送端的时间戳(Timestamp Value field,TSval,4字节),时间戳回显应答(Timestamp Echo Reply field,TSecr,4字节)

    • 19:MD5 摘要,将 TCP 伪首部、校验和为0的TCP首部、TCP数据段、通信双方约定的密钥(可选)计算出MD5摘要值并附加到该选项中,作为类似对TCP报文的签名。通过 RFC 2385 引入,主要用于增强 BGP 通信的安全性。

    • 29:安全摘要,通过 RFC 5925 引入,将“MD5摘要”的散列方法更换为SHA散列算法。

Linux中TCP头结构体定义如下:

 struct tcphdr {
     __be16  source;
     __be16  dest;
     __be32  seq;
     __be32  ack_seq;
     #if defined(__LITTLE_ENDIAN_BITFIELD)
     __u16   res1:4,
             doff:4,
             fin:1,
             syn:1,
             rst:1,
             psh:1,
             ack:1,
             urg:1,
             ece:1,
             cwr:1;
     #elif defined(__BIG_ENDIAN_BITFIELD)
     __u16   doff:4,
             res1:4,
             cwr:1,
             ece:1,
             urg:1,
             ack:1,
             psh:1,
             rst:1,
             syn:1,
             fin:1;
     #else
     #error  "Adjust your <asm/byteorder.h> defines"
     #endif
     __be16  window;
     __sum16 check;
     __be16  urg_ptr;
 };

2、TCP协议的基本特点

面向连接

  • TCP协议在传输数据之前,必须先建立TCP连接,并在数据传送完毕后释放连接。

  • 每一条TCP连接只能有两个端点,且是点对点的(一对一)。

可靠传输

  • TCP提供可靠交付的服务,通过TCP连接传送的数据无差错、不丢失、不重复,并且按序到达。

  • TCP采用发送应答机制,发送的每个报文段都必须得到接收方的应答才认为传输成功。

  • TCP使用校验和来检验数据是否有错误,并在发送和接收时都计算校验和。

全双工通信

  • TCP允许通信双方的应用进程在任何时候都能发送数据。

  • TCP连接的两端都设有发送缓存和接收缓存,用来临时存放双向通信的数据。

面向字节流

  • TCP将应用程序交下来的数据看成是一连串的无结构的字节流。

  • TCP不保证接收方应用程序所收到的数据块和发送方应用程序所发出的数据块具有对应大小的关系。

3、三次握手(TCP协议的连接建立)

TCP连接的建立过程通常被称为“三次握手”,具体步骤如下:

第一次握手

  • 客户端向服务端发送一个SYN报文段(同步序列编号SYN=1),并包含一个初始序列号ISN(Initial Sequence Number)。

第二次握手

  • 服务端收到SYN报文段后,以自己的ISN回应(SYN=1),并确认收到客户端的SYN报文段(ACK=1,确认号为客户端的ISN+1)。

第三次握手

  • 客户端收到服务端的SYN+ACK报文段后,向服务端发送一个ACK报文段(ACK=1,确认号为服务端的ISN+1),至此TCP连接建立完成。

4、为什么三次握手?而不是二次、四次握手?

采用三次握手有三个原因:

  • 防止重复历史连接的初始化(主要原因);

  • 同步双方的初始化序列号 ISN;

  • 避免资源浪费。

不使用两次握手和四次握手的原因:

  • 两次握手:无法防止历史连接的建立,会造成双方资源的浪费,也无法可靠的同步双方序列号;

  • 四次握手:三次握手就已经理论上最少可靠连接建立,所以不需要使用更多的通信次数。

5、TCP三次握手中的异常情况

5.1 异常一:第一次握手丢了

客户端给服务端发的 SYN 包丢失后,也就不会收到 SYN+ACK,然后会启动「超时重传」,重传的 SYN 包的序列号都是一样的。

在 Linux 里,客户端的 SYN 包最大重传次数由 tcp_syn_retries 内核参数控制,可以修改,默认值一般是 6。

 # cat /proc/sys/net/ipv4/tcp_syn_retries 
 6

第一次超时重传是在 1 秒后,第二次在 2 秒后,第三次在 4 秒后,第四次在 8 秒后,第五次在 16 秒后,第六次在 32 秒后。每次超时的时间是上一次的 2 倍。

当第六次超时重传后,会继续等待 32 秒,如果服务端仍然没有回应 ACK,客户端就不再发送 SYN 包,然后断开 TCP 连接。所以,总耗时是 1+2+4+8+16+32+64=127 秒,大约 2 分钟左右。

5.2 异常二:第二次握手丢了

服务器给客户端发的 SYN + ACK 包丢了,会造成双方超时重传:

  • 客户端迟迟收不到服务端回应的 ACK,发生超时重传,重传 SYN,和上面第一次握手丢了一样,第五次超时重传超时后断开连接;

  • 服务端发了SYN,也需要客户端回应 ACK包,不然也会超时重传,重传 SYN+ACK。第五次重传超时后断开连接。

在 Linux 下,SYN+ACK 报文的最大重传次数由 tcp_synack_retries 内核参数决定,默认值是 5。

 # cat /proc/sys/net/ipv4/tcp_synack_retries 
 5

5.3 异常三:第三次握手丢了

客户端发给服务端的 ACK 包丢了,会导致服务端超时重传 SYN+ACK,而不是客户端超时重传ACK包,这里强调下,所有 ACK 不会「超时重传」。

和上面第二次握手丢了服务端的行为一样,第 tcp_synack_retries 次超时重传超时后,服务端断开连接。但是客户端已经是 ESTABLISHED 状态,最后会因为发送数据失败,关闭连接。

5.4 异常四:SYN 攻击与避免

攻击者短时间伪造大量不同的 IP 地址发送 SYN 报文,服务端每接收到一个 SYN 报文,就进入SYN_RCVD 状态,但服务端发给伪 IP的的 ACK+SYN 报文,无法得到回应 ACK 报文,不停的往「半连接队列」塞数据,打满半连接队列,后续再收到 SYN 报文就会丢弃,导致其他正常的客户端无法和服务端建立连接。

开启 net.ipv4.tcp.tcp_syncookies,可以解决 SYN 攻击。参数有下面三个值:

  • 0 值,表示关闭该功能;

  • 1 值,表示仅当 「SYN 队列」满时,再启用它;

  • 2 值,表示无条件开启功能。

开启 syncookies 功能可以绕过「SYN 队列」成功建立连接。过程如下图:

  • 当「 SYN 队列」被打满后,后续服务端收到 SYN 包,不会丢弃,而是根据算法(通过原地址端口,目的地址端口和时间戳打造一个特别的Sequence Number)计算出一个 cookie 值;将 cookie 值放到第二次握手报文的「序列号」里,然后发给客户端;

  • 客户端收到 SYN+ACK 包后,正常回应 ACK cookie+1;攻击者伪装的 IP 不会应答;

  • 服务端接收到客户端的应答报文时,服务端会检查这个 ACK 包的合法性。如果合法,将该连接对象放入到「 Accept 队列」。

  • 最后应用程序通过调用 accpet() 接口,从「 Accept 队列」取出连接对象。

那么在应对 SYN 攻击时,只需要设置 tcp_syncookies 为 1,命令如下:

 $ echo 1 > /proc/sys/net/ipv4/tcp_syncookies

6、四次挥手(TCP协议的连接释放)

图片

TCP连接的释放过程通常被称为“四次挥手”,具体步骤如下:

第一次挥手

  • 客户端发送给服务器一个请求释放连接的数据包,即发送了一个指向服务器目标端口的一个 FIN 位为 1 的TCP 报文,表示客户端没有数据要发送了,但是仍然可以接收数据;并且 ACK 位也为 1,表示对上次传输数据结果的确认。并且之后处去等待状态,等待服务器的两次回应。

第二次挥手

  • 服务器接收到客户端的释放连接请求之后,会先回应一个 ACK 位为 1 的报文,表示确认收到。但是,这时服务器可能还有数据没有发送完成,继续发送数据。

第三次挥手

  • 服务器发送完数据之后,发送一个 FIN 为 1 的 TCP 报文,表示我也没有要发送的数据了,你可以释放连接了。当然 ACK 位仍然为 1 。

第四次挥手

  • 客户端接收到服务器的同意释放连接的数据包之后,回复一个 ACK 为 1 的 TCP 报文,表示确认收到。

7、TCP四次挥手中的异常情况

7.1 第一次挥手丢了

当「主动方」调用 close 函数后,就会向「被动方」发送 FIN 报文,此时客户端的连接进入 FIN_WAIT_1 状态。

如果第一次挥手丢失了,那么「主动方」迟迟收不到「被动方」的 ACK 的话,就会触发超时重传 FIN 报文,重发次数由 tcp_orphan_retries 参数(默认 0)控制。超时重传次数超过 tcp_orphan_retries 后,再等一段时间(指数增加)还是没有收到第二次握手,就关闭连接。

 # cat /proc/sys/net/ipv4/tcp_orphan_retries
 0

7.2 第二次挥手丢了

在前面提过,ACK 报文不会超时重传,所以如果「被动方」的第二次挥手丢失了,「主动方」就会超时重传 FIN 报文,直到收到服务端的第二次挥手。与第一次挥手丢失行为一样。

7.3 第三次挥手丢了

当「主动方」收到第二次挥手 ACK 后,进入 FIN_WAIT_2 状态。

对于调用 close 函数主动关闭的连接,由于无法再发送和接收数据,所以 FIN_WAIT2 状态不可以持续太久,会启用一个计时器,时间长度由 tcp_fin_timeout 控制,默认60秒,如果计时器超时了还没有收到第三次挥手 FIN 报文,就直接进入 CLOSED 状态。

 # cat /proc/sys/net/ipv4/tcp_fin_timeout
 60

但是对于调用 shutdown 函数主动关闭的连接,只关闭发送方向,没有关闭接收方向,没有计时器。如果「主动方」一直没收到第三次挥手,那么「主动方」将会一直处于 FIN_WAIT2 状态。

「被动方」处于 CLOSE_WAIT 状态时,调用 close 函数,内核会发出 FIN 报文,然后进入 LAST_ACK 状态,等待「主动方」返回 ACK 来确认连接关闭。如果第三次挥手 ACK 丢失了,「被动方」就会超时重传 FIN 报文,重发次数仍然由 tcp_orphan_retries 参数决定,最后还是没有收到直接进入 CLOSED 状态。

7.4 第四次挥手丢了

如果第四次挥手的 ACK 报文丢了,「被动方」就会超时重传 FIN 报文,重发次数仍然由 tcp_orphan_retries 参数决定。「主动方」在收到 FIN 后,进入 TIME_WAIT 状态,开启时长为 2MSL 的计时器,如果途中再次收到第三次挥手 FIN 报文后,就会重置 2MSL 的计时器。如果第四次挥手一直丢失,但是第三次挥手不丢失,会使「主动方」迟迟关闭不了连接。

8、抓包分析TCP协议

利用 wireshark 工具抓包分析可以很清晰的看到这两个流程。

  • 打开 wireshark 软件 开启抓包,过滤规则设置为 tcp 。

  • 开发板连接上网络后,运行 samples 里面的 tcp client 例程,

这样就可以很方便的看到 TCP 的三次握手与四次挥手的全过程,如下图所示:

9、TCP协议的应用场景

TCP协议因其可靠性高、支持流量控制和拥塞控制等特点,广泛应用于对数据可靠性要求高、顺序要求严格的应用场景,如:

  • 网页浏览:HTTP协议通常使用TCP作为传输层协议,确保网页内容的完整性和可靠性。

  • 电子邮件:SMTP、POP3和IMAP等邮件协议使用TCP协议进行可靠的邮件传输。

  • 文件传输:FTP协议使用TCP进行文件的可靠传输。

  • 实时通信:如语音通话、视频通话等应用需要保证数据的完整性和顺序,通常选择TCP协议。

 

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

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

相关文章

LLM用于时序预测真的不行,连推理能力都没用到

语言模型真的能用于时序预测吗&#xff1f;根据贝特里奇头条定律&#xff08;任何以问号结尾的新闻标题&#xff0c;都能够用「不」来回答&#xff09;&#xff0c;答案应该是否定的。事实似乎也果然如此&#xff1a;强大如斯的 LLM 并不能很好地处理时序数据。 时序&#xff0…

Prometheus监控主机进程

前言 客户端安装及配置 Premetheus服务端配置 模板导入 grafana效果图 前言 此场景主要是利用process-export监控主机的进程存活、资源占用率&#xff0c;防止进程挂掉导致服务崩溃 gitlab地址&#xff1a;GitHub - ncabatoff/process-exporter: Prometheus exporter that…

开发体育直播平台:高并发问题解决手段及架构设计思路

在追求极致观赛体验的体育直播领域&#xff0c;高并发处理能力成为了衡量系统性能与稳定性的关键标尺。东莞梦幻网络科技技术团队&#xff0c;凭借其在互联网领域的深厚积累与前瞻视野&#xff0c;成功打造了一套高效、稳定的体育赛事直播系统&#xff0c;有效解决了高并发带来…

【Python】sklearn教程

1. sklearn库介绍 sklearn是 Python 中一个非常重要的机器学习库&#xff0c;全称为scikit-learn。它是基于Python语言的机器学习工具&#xff0c;提供了一系列简单高效的机器学习算法。sklearn库通常与NumPy和SciPy库一起使用&#xff0c;用于数据预处理、特征选择、模型训练…

Centos 使用nfs配置共享目录使docker集群所有容器日志统一主机访问

Centos 使用nfs配置共享目录&#xff0c;使docker集群所有容器日志统一存放在主机一个共享目录下&#xff0c;供开发人员访问查看 准备两台或以上Centos服务器 192.168.0.1 nfs服务器 192.168.0.2 nfs客户端 以root用户登录192.168.0.1服务器&#xff0c;执行以下操作 注意先…

【JavaScript】解决 JavaScript 语言报错:Uncaught SyntaxError: Unexpected identifier

文章目录 一、背景介绍常见场景 二、报错信息解析三、常见原因分析1. 缺少必要的标点符号2. 使用了不正确的标识符3. 关键词拼写错误4. 变量名与保留字冲突 四、解决方案与预防措施1. 检查和添加必要的标点符号2. 使用正确的标识符3. 检查关键词拼写4. 避免使用保留字作为变量名…

ReentrantLock的源码实现和原理介绍

目录 一、概述 二、ReentrantLock的整体结构 三、ReentrantLock 和Synchronized相比 四、ReentrantLock 公平锁和非公平锁实现 4.1 ReentrantLock 源码解读 4.1.1 ReentrantLock 类源码解读 4.1.1.1 Lock接口 4.1.1.2 Sync抽象类 4.1.1.3 NonfairSync()和FairSync() 4…

《0基础》学习Python——第十讲

小知识点补充 一、json大字符串 JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;它以易于阅读和编写的方式为基础&#xff0c;同时也易于解析和生成。因为其简洁性和可读性&#xff0c;JSON已成为数据交换的首选格式。 大字符…

超大模型加载转换Trick

在深度学习领域&#xff0c;大模型的训练和推理通常需要消耗大量的计算和内存。如何高效地加载和使用大模型是一个相当关键的问题。在这篇博客中&#xff0c;我将分享一些关于更快加载大模型和减少内存的技巧。 1.问题分析 假设现在我们有一个236B 超大模型的原始权重的 check…

jmeter-beanshell学习9-放弃beanshell

写这篇时候道心不稳了&#xff0c;前面写了好几篇benashell元件&#xff0c;突然发现应该放弃。想回去改前面的文章&#xff0c;看了看无从下手&#xff0c;反正已经这样了&#xff0c;我淋了雨&#xff0c;那就希望别人也没有伞吧&#xff0c;哈哈哈哈&#xff0c;放在第九篇送…

DHCP原理及配置

目录 一、DHCP原理 DHCP介绍 DHCP工作原理 DHCP分配方式 工作原理 DHCP重新登录 DHCP优点 二、DHCP配置 一、DHCP原理 1 DHCP介绍 大家都知道&#xff0c;现在出门很多地方基本上都有WIFI&#xff0c;那么有没有想过这样一个问题&#xff0c;平时在家里都是“固定”的…

互联网十万个为什么之什么是专有网络VPC?

专有网络VPC有什么优势&#xff1f; 专有网络VPC具有安全可靠、灵活可控、简单易用的特性和较强的可扩展性。 安全可靠 每个VPC都有一个独立的隧道号&#xff0c;一个隧道号对应着一个虚拟化网络。VPC之间通过隧道号进行隔离&#xff1a; 由于VPC内部存在交换机和路由器&#…

PyTorch人脸识别

新书速览|PyTorch深度学习与企业级项目实战-CSDN博客 一套基本的人脸识别系统主要包含三部分&#xff1a;检测器、识别器和分类器&#xff0c;流程架构如图11-3所示&#xff1a; 图11-5 检测器负责检测图片中的人脸&#xff0c;再将检测出来的人脸感兴趣区域&#xff08;Reg…

如何在单片机外部Flash存储器上部署高效文件系统:从原理到实现

目录 1.Littlefs文件系统 1.1文件系统简介 2 Littlefs文件系统移植到单片机上 2.1 添加源代码 2.2 编辑接口函数 2.3 测试代码 1.Littlefs文件系统 1.1文件系统简介 littlefs文件系统源码下载地址&#xff1a;littlefs-project/littlefs: A little fail-safe filesystem…

Unity Shader学习笔记

Shader类型 类型详情Standard Surface Shader标准表面着色器&#xff0c;基于物理的着色系统&#xff0c;用于模拟各种材质效果&#xff0c;如石头、木材、玻璃、塑料和金属等。Unlit Shader最简单的着色器&#xff0c;不包含光照但包含雾效&#xff0c;只由最基础的Vertex Sh…

Pytorch使用Dataset加载数据

1、前言&#xff1a; 在阅读之前&#xff0c;需要配置好对应pytorch版本。 对于一般学习&#xff0c;使用cpu版本的即可。参考教程点我 导入pytorch包&#xff0c;使用如下命令即可。 import torch # 注意虽然叫pytorch&#xff0c;但是在引用时是引用torch2、神经网络获取…

【C++】—— 初识C++

【C】—— 初识C 一、什么是 C二、C 的发展历史三、C 版本更新四、C 的重要性五、C 在工作领域中的运用六、C 书籍推荐&#xff1a; 一、什么是 C C语言 是结构化和模块化的语言&#xff0c;适合处理较小规模的程序。对于复杂的问题&#xff0c;规模较大的程序&#xff0c;需要…

六、STM32F4+标准库+LWIP2.1.2移植+无操作系统

最快最简单的移植LWIP协议栈&#xff0c;可改可不改的东西统一不修改。后期学会了有能力了再回过头来修改&#xff0c;操作复杂理论复杂&#xff0c;同时讲解对新手不是很友好&#xff0c;故此此文档只讲操作无任何理论讲解。 零、所需文件及环境 1、第四章建立好的串…

51单片机11(蜂鸣器硬件设计和软件设计)

一、蜂鸣器硬件设计 1、 2、上面两张图&#xff0c;是针对不同产品的电路图。像左边这一块&#xff0c;是我们的A2&#xff0c;A3&#xff0c;A4的一个产品对应的一个封闭器的硬件电路。而右边的这一块是对应的A5到A7的一个硬件电路。因为A5到A7的一个产品&#xff0c;它的各…

排序算法3_冒泡排序、快速排序

一、冒泡排序 1.1 冒泡排序定义和思路 冒泡排序的基本思想是&#xff1a;通过相邻两个元素之间的比较和交换&#xff0c;使较大的元素逐渐从前面移向后面&#xff08;升序&#xff09;&#xff0c;就像水底下的气泡一样逐渐向上冒泡&#xff0c;所以被称为“冒泡”排序。  在…