【Linux-网络】从逻辑寻址到物理传输:解构IP协议与ARP协议的跨层协作

news2025/7/15 18:48:57

52bc67966cad45eda96494d9b411954d.png

🎬 个人主页:谁在夜里看海.

📖 个人专栏:《C++系列》《Linux系列》《算法系列》

⛰️ 道阻且长,行则将至


目录

📚前言

📖 IP地址的组成

🔖IPv4

🔖IPv6

📚 一、IP协议(网络层)

📖 1. 报头格式

📖 2. 网段划分

📖 3. 公网&私有IP

📖 4. 路由选择

🔖原理

🔖类型

📚二、ARP协议(数据链路层)

📖 1. 以太网

📖 2. ARP协议

🔖格式


📚前言

上一篇文章我们详细介绍了TCP/UDP协议。当数据在应用层完成编写后,传输层会接收到这些数据并进行进一步封装,添加源端口号、目的端口号等信息,以确保数据包能够正确地交付给目标主机上的相应进程进行处理。今天,我们要介绍的IP协议,主要解决的是数据包如何从一台主机传输到另一台主机的问题。

理解IP协议之前,我们需要清楚一个基础概念:什么是IP地址。

IP地址(Internet Protocol Address,互联网协议地址)是分配给网络中每一台设备的唯一标识符,用于计算机在网络中定位和识别设备。有了IP地址,就可以在网络中定位目标主机,传输数据了。(并不严谨)

上述说法是比较笼统的,在具体应用中,IP地址并非唯一标识设备,也无法仅通过IP地址完成数据的传输,原因之一是,网络中设备数量太过庞大,IP地址数量不足:

📖 IP地址的组成

IP地址主要分为两种版本:

① IPv4地址;② Ipv6地址

🔖IPv4

IPv4是一个32位的二进制数字,即由4个字节组成,每个字节表示一个0到255之间的整数,以“点分十进制”书写。例如:192.168.1.1

因此IPv4支持大约43亿个(2^32)独立地址,看似很大,但由于互联网设备的爆发式增长,IPv4已近乎枯竭。

面对资源枯竭的一个解决办法是,改用地址范围更大的IPv6

🔖IPv6

IPv6地址是一个128位的二进制数字,由16个字节组成,划分为八组十六进制数字,每组之间用冒号(:)分隔,例如:2001:0db8:85a3:0000:0000:8a2e:0370:7334

IPv6提供了340万亿个地址(2^128),这一数量远远超过了IPv4的地址数量,能够满足未来互联网设备的需求。 

但是地址版本替换是一个很麻烦的事情, 面临版本不兼容、设备升级、网络配置等多方面的挑战,IPv4到IPv6的过渡是一个漫长且复杂的过程,需要协调各国和各地区的网络运营商、硬件厂商、软件供应商等,分阶段逐步过渡。

应对上述问题,下面我们会介绍到划分方案、私有IP等概念。 

📚 一、IP协议(网络层)

📖 1. 报头格式

在网络层,我们通过IP协议完成数据的封装与转发,与TCP/UDP协议一样,IP协议会给数据包添加对应的IP报头,下面是IP协议的报头格式:

下面我们分别对各个字段进行介绍:

① 版本:该字段指定了IP协议的版本。IPv4的值为4,IPv6的值为6

② 首部长度:该字段指示IP报头的实际长度(单位是32位字,即4字节)。默认情况下,IHL的值为5,表示IP报头的长度为5个32位字(即20字节)

❓为什么需要首部长度字段?

✅因为IP报头和TCP报头一样,存在选项字段,即报头总长不定,需要明确标注。

❓为什么单位是32位(4字节)

✅因为报头的字段基本以32位为一组(源IP地址、目的IP地址都是32位),由此我们也可得知,选项字段也必须以32位为一组。

③ 类型服务:该字段用于提供服务质量(QoS)控制。3位优先权字段(已经弃用), 4位TOS字段, 和1位保留字段(必须置为0)。4位 TOS分别表示: 最小延时, 最大吞吐量, 最高可靠性, 最小成本。这四者相互冲突, 只能选择一个。对于 ssh/telne t这样的应用程序, 最小延时比较重要; 对于 ftp 这样的程序, 最大吞吐量比较重要。

④ 总长度:该字段指示整个IP数据包的总长度,包括头部和数据部分。单位是1字节,最大值为65535字节(2^16),表示总长度最大约为64k字节。

⑤ 标识:在IP数据包分片时,这个字段为所有分片提供一个唯一标识符。每个分片都包含相同的标识符,以便接收方将它们正确地组合在一起。

⑥ 标志:标志字段的作用是指示数据包是否允许分片。它包含3位:

第1位(保留,通常为0)

第2位:Don't Fragment (DF),如果该位为1,则指示数据包不能分片。

第3位:More Fragments (MF),如果该位为1,则说明数据包后面还有更多的分片。

⑦ 片偏移:该字段表示当前分片相对于原始数据包的偏移量。单位为8字节(64位),如果偏移量为1,则表示当前分片从第9个字节开始。

🔖分片

由于在网络中存在最大传输单元(MTU),当数据包的长度大于当前网络的最大传输单元时,需要对数据包分片,以符合传输限制。分片后肯定要对数据进行重组,将数据包还原,然而我们怎么知道数据片原来属于哪个数据包呢,就要通过标识字段。我们在重组数据包时,要确保数据片的顺序正确,这就要通过片偏移字段来完成。

数据包分片后,每个片段都会拥有独立的IP报头,作为独立的IP数据包来传输,通过标识字段、分片偏移量、分片标志这些字段内容,接收端能够识别哪些分片属于同一个数据包,并在收到所有片段后将它们重新组合成完整的数据包

⑧ 生活时间:TTL字段的目的是限制数据包在网络中的生命时间。每经过一个路由器,TTL值就减1,直到TTL为0时,数据包会被丢弃。TTL字段的目的是防止数据包在网络中无限循环

⑨ 协议:用于指示数据包的上层协议。6表示TCP协议;17表示UDP协议;1表示ICMP协议

⑩ 头部校验和:该字段用于检测IP头部在传输过程中是否发生了错误。接收方通过计算报头的校验和来检查数据的完整性。 

⑪ 源IP地址:包含发送方的IP地址,用于标识数据包的来源。

⑫ 目的IP地址:包含接收方的IP地址,用于指示数据包的目的地。

⑬ 选项:选项字段是可选的,包含一些额外的控制信息,例如时间戳、路由记录等。

📖 2. 网段划分

IP地址的分配并不是随意的,而是遵循一定的规则和结构。这种规则主要体现在网段划分上。IP地址分为两个部分,网络号和主机号。

为了方便网络寻址和设备管理,我们将网络上的设备归类为一个个网段中,位于同一个网段下的设备拥有相同的网络号,在网段内部,通过主机号区分每个设备。然而手动分配主机号会相当麻烦,于是有一种技术叫做 DHCP , 能够自动的给子网内新增主机节点分配IP地址, 避免了手动管理IP的不便。一般的路由器都带有DHCP功能,因此路由器也可以看做一个DHCP服务器。

❓问题来了,网络号和主机号该如何进行划分呢,如果随意划分,既不利于网络中的IP寻址,也不利于IP地址的分配管理,于是需要将划分规范化。下面是一种划分网络号和主机号的方案, 把所有IP 地址分为五类:

A类 0.0.0.0到127.255.255.255;

B类 128.0.0.0到191.255.255.255;

B类 128.0.0.0到191.255.255.255;

D类 224.0.0.0到239.255.255.255;

E类 240.0.0.0到247.255.255.255 。

⚠️但是这种划分方式会造成一个问题,就是IP地址的大量浪费。

在这种划分方式中,主机号位数越多,同一网段下支持的设备数量就越多,但同时网段数量就越少,因此我们希望主机号和网络号的位数趋于合理,同时满足设备数量与网段数量的需求。在实际使用中,大多数组织都申请B类网络地址, 导致B类地址很快就 分配完了, 而A类存在大量地址浪费,这是我们不愿意看到的。

✅针对这种情况提出了新的划分方案, 称为CIDR(Classless Interdomain Routing):

引入一个额外的子网掩码(subnet mask)来区分网络号和主机号,子网掩码也是一个32位的正整数,将IP地址与子网掩码进行按位与操作,得到的结果就是网络号。有了子网掩码,我们就可以依据现实情况,动态调整网段可容纳的设备数量。这样一来,大大提升了IP地址的使用效率。

例如:IP地址为 140.252.10.68,子网掩码为 255.255.255.0 时,网络号为 140.252.20.0,子网地址范围为 140.252.20.0 ~ 140.252.20.255。

可见,IP地址与子网掩码做与运算可以得到网络号,主机号从全0到全1就是子网的地址范围;IP地址和子网掩码还有一种更简洁的表示方法,例如140.252.20.68/24,表示IP地址为140.252.20.68, 子网掩码的高 24位是1,也就是255.255.255.0。

🔖下面有几个特殊的IP地址

① 网络号:将IP地址中的主机地址全部设为0, 就成为了网络号, 代表这个局域网;

② 广播地址:将IP地址中的主机地址全部设为1, 就成为了广播地址, 用于给同一个链路中相互连接的所有主机发送数 据包;

③ 127.0.0.1:127.*的IP地址用于本机环回(loop back)测试,通常为127.0.0.1。

📖 3. 公网&私有IP

我们上面提到,IPv4的IP数量不能满足现如今大量网络设备的需求,针对这一问题,使用私有IP是一个很好的办法。如果一个组织内部组建局域网,IP地址只用于局域网内的通信,而不直接连到Internet上,就可以使用私有IP,私有IP独立于公网IP,不同局域网内也可以使用相同的私有IP,这样一来,极大缓解了IP地址不足的问题,因为我们不需要给每一个设备都分配公网IP了

但是私有IP的分配也不是随意的,我们需要将私有IP与公有IP区分开来,私有IP和公有IP我们需要一目了然:如果是私有IP,就可以直接在局域网中寻址;如果是公有IP,就需要进行跨网段寻址。RFC 1918规定了用于组建局域网的私有IP地址。

1️⃣A类地址:10.*,前8位是网络号,共16,777,216个地址;

2️⃣B类地址:172.16.* ~ 172.31.*,前12位是网络号,共1,048,576个地址;

3️⃣C类地址:192.168.*,前16位是网络号,共65,536个地址。

⚠️包含在这个范围中的,都是私有IP,其余的则称为全局IP(或公网IP)。

我们该怎么区分每一个网段呢?

✅每一个网段都有一个接口,确定当前网段的网络号子网掩码,位于当前网段的所有设备都与这个接口连接,并且通过这个接口与外界实现通信,这个接口就是网关,路由器是最常见的网关设备

对于一个路由器,其可以配置两个IP地址,分别是WAN口IP、LAN口IP(子网IP):例如LAN为10.1.1.1/24的路由器,表示该路由器的网段网络号为10.1.1.0,设备IP范围是10.1.1.2 ~ 10.1.1.254

而每一个家用路由器,其实又作为运营商路由器的子网中的一个节点这样的运营商路由器可能会有很多级, 最外层的运营商路由器, WAN口IP就是一个公网IP了;子网内的主机想要和外网进行通信时,路由器将IP首部中的IP地址进行替换(替换成WAN IP),这样逐级替换,最终数据包中的IP地址成为一个公网IP,这种技术被称为NAT(Network Address Translation,网络地 址转换)。

📖 4. 路由选择

数据包从源设备传输到目标设备的过程,涉及到如何根据目标地址选择合适的路径进行数据转发,这就需要路由器来进行路由选择,它会根据路由表决定数据包的转发路径。

🔖原理

① 路由表

每个路由器都有一个路由表,记录了网络中所有可能的目的地和相应的转发路径。路由表包含了目标网络的地址、下一跳的地址(下一台路由器的地址)、以及路由的优先级(距离、延迟等)。

② 路由决策

当数据包到达路由器时,路由器查看数据包的目标IP地址,然后根据路由表决定下一跳路由器(或目标设备)将数据包传递到哪里。每一个路由器都会依此做出决策,直到数据包到达目标设备。

③ 下一跳

指的是数据包在通过路由器时,路由器根据路由表选定的下一个跳转点。它可以是另一个路由器或最终的目标主机。

④ 最优路径

路由选择的目标是找到一条有效、最优的路径。最优路径不仅是最短的路径,还可能考虑其他因素,如带宽、延迟、可靠性等。

例如:某主机的网络接口配置和路由表如下:

Destination:目的网络地址

Gateway:下一跳地址

Genmask:子网掩码

Flags:U标志表示此条目有效(可以禁用某些 条目),G标志表示此条目的下一跳地址是某个路由器的地址,没有G标志的条目表示目的网络地址是与本机接口直接相连的网络,不必经路由器转发

Iface:发送接口

这台主机有两个网络接口,一个网络接口连到192.168.10.0/24网络,另一个网络接口连到 192.168.56.0/24网络。如果要发送的数据包的目的地址是192.168.56.3:

1. 与第一行的子网掩码做与运算得 到192.168.56.0,与第一行的目的网络地址不符;

2. 再与第二行的子网掩码做与运算得到192.168.56.0,正是第二行的目的网络地址,因此从eth1接口发送

 如果要发送的数据包的目的地址是202.10.1.2:

1. 与路由表前几项进行对比,发现都不匹配;

2. 按缺省路由条目,从eth0接口发出去,发往192.168.10.1路由器;

3. 由192.168.10.1路由器根据它的路由表决定下一跳地址;

🔖类型

① 静态路由

静态路由是由网络管理员手动配置的路由。在网络的路由表中,静态路由条目不会自动改变,只有在手动修改时才会更新。用于小型网络或一些特定的网络环境中,可以提供简单且明确的路由路径

② 动态路由

动态路由是通过路由协议自动发现和维护路由信息的过程。路由器会定期交换路由信息,自动更新路由表,以适应网络拓扑的变化。常用于较大的、不断变化的网络环境。

📚二、ARP协议(数据链路层)

📖 1. 以太网

然而仅通过IP地址,我们还是不能够实现网络通信。原因很简单,数据包最后是交给网卡进行处理,而网卡对IP地址是没有概念的,它只认MAC地址,因为MAC地址是网卡设备在出厂时烧录进硬件的信息,所以在底层,是通过MAC地址进行数据传输的

🔖MAC地址

每个网络设备(如网卡、交换机、路由器等)在出厂时会由制造商根据全球唯一的规则分配MAC地址,且通常不可更改,换句话说,MAC地址唯一标识网络设备,由6个字节(48位)组成:

00:1A:2B:3C:4D:5E  或  00-1A-2B-3C-4D-5E

于是当网络层的IP数据包交付给数据链路层时,还需要进一步封装,添加源MAC和目的MAC地址等信息:

在局域网中,数据通过MAC地址定位目标主机来传输,这种技术就是以太网。上述格式就是以太网帧格式

 源地址和目的地址是指网卡的硬件地址(也叫MAC地址), 长度是48位,在网卡出厂时确定;

 帧协议类型字段有三种值,分别对应IP、ARP、RARP;

 帧末尾是CRC校验码。

📖 2. ARP协议

但是源主机在网络通讯时,只知道目的主机的IP地址和端口号,却不知道目的主机的硬件地址,所以在数据链路层,需要将IP地址转换成对应的MAC地址,ARP协议的作用就是建立了主机 IP地址 和 MAC地址 的映射关系。因此网络通信的过程为:

① 得知目标主机IP地址;

② 向局域网广播,申请MAC地址回复;

③ 收到MAC地址,封装数据包,进行数据传输。

其中第二步就是ARP协议需要进行工作。下面举个例子:

1. 源主机发出ARP请求,询问“IP地址是192.168.0.1的主机的硬件地址是多少”,并将这个请求广播到本地网段(以太网帧首部的硬件地址填FF:FF:FF:FF:FF:FF表示广播);

2. 目的主机接收到广播的ARP请求,发现其中的IP地址与本机相符,则发送一个ARP应答数据包给源主机,将自己的硬件地址填写在应答包中;

3. 每台主机都维护一个ARP缓存表,可以用arp -a命令查看。缓存表中的表项有过期时间(一般为20分钟),如果20分钟内没有再次使用某个表项,则该表项失效,下次还要发ARP请求来获得目的主机的硬件地址

❓为什么ARP缓存表需要过期机制

1️⃣在局域网内,设备的IP地址有可能发生变化,如果ARP缓存没有过期或更新,设备仍然会尝试使用旧的MAC地址进行通信,导致数据包无法正确送达目标设备

2️⃣网络中的ARP缓存可能被恶意篡改(例如ARP欺骗攻击),这可能导致数据包被错误地转发到攻击者设备。过期机制能够确保ARP缓存表中的信息定期被更新,这有助于防止恶意攻击

🔖格式

 下面是ARP数据报的格式:

① 硬件类型指链路层网络类型,1为以太网;

② 协议类型指要转换的地址类型,0x0800为IP地址;

③ 硬件地址长度对于以太网地址为6字节;

④ 协议地址长度对于和IP地址为4字节;

⑤ op字段为1表示ARP请求,op字段为2表示ARP应答。


以上就是【从逻辑寻址到物理传输:解构IP协议与ARP协议的跨层协作】的全部内容,欢迎指正~ 

码文不易,还请多多关注支持,这是我持续创作的最大动力!

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

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

相关文章

解锁前端表单数据的秘密旅程:从后端到用户选择!✨

😄 解锁前端表单数据的秘密旅程:从后端到用户选择!✨ 嘿,技术爱好者们!👋 你有没有在开发中遇到过这样的困惑:表单里的数据(比如图片附件、识别点 ID)从哪儿来的&#x…

【机械视觉】C#+visionPro联合编程———【一、C# + VisionPro 联合编程详解以及如何将visionPro工具加载到winform】

机械视觉与 C# VisionPro 联合编程详解 目录 机械视觉与 C# VisionPro 联合编程详解 概念 应用场景 1. 工业检测与质量控制缺陷检测 2. 定位与机器人引导 3. 识别与分类 4. 复杂流程控制 将visionPro工具加载到winform 环境准备 一、创建winform项目 二、打开窗体…

江科大51单片机笔记【9】DS1302时钟可调时钟(下)

在写代码前,记得把上一节的跳线帽给插回去,不然LCD无法显示 一.DS1302时钟 1.编写DS1302.c文件 (1)重新对端口定义名字 sbit DS1302_SCLKP3^6; sbit DS1302_IOP3^4; sbit DS1302_CEP3^5;(2)初始化 因为…

发行思考:全球热销榜的频繁变动

几点杂感: 1、单机游戏销量与在线人数的衰退是剧烈的,有明显的周期性,而在线游戏则稳定很多。 如去年的某明星游戏,最高200多万在线,如今在线人数是48名,3万多。 而近期热门的是MH,在线人数8…

微信小程序接入deepseek

先上效果 话不多说&#xff0c;直接上代码&#xff08;本人用的hbuilder Xuniapp&#xff09; <template><view class"container"><!-- 聊天内容区域 --><scroll-view class"chat-list" scroll-y :scroll-top"scrollTop":…

为解决局域网IP、DNS切换的Windows BAT脚本

一、背景 为解决公司普通人员需要切换IP、DNS的情况&#xff0c;于是搞了个windows下的bat脚本&#xff0c;可以对有线网络、无线网络进行切换设置。 脚本内容 echo off title 多网络接口IP切换工具:menu cls echo echo 请选择要配置的网络接口: echo echo 1. 有线网络&am…

VUE3开发-9、axios前后端跨域问题解决方案

VUE前端解决跨域问题 前端页面需要改写 如果无效&#xff0c;记得重启服务器 后端c#解决跨域问题 前端js取值&#xff0c;后端c#跨域_c# js跨域-CSDN博客

【计算机网络】计算机网络的性能指标——时延、时延带宽积、往返时延、信道利用率

计算机网络的性能指标 导读 大家好&#xff0c;很高兴又和大家见面啦&#xff01;&#xff01;&#xff01; 在上一篇内容中我们介绍了计算机网络的三个性能指标——速率、带宽和吞吐量。用大白话来说就是&#xff1a;网速、最高网速和实时网速。 相信大家看到这三个词应该就…

Kubermetes 部署mysql pod

步骤 1: 创建 PersistentVolume 和 PersistentVolumeClaim 首先为 MySQL 创建一个 PersistentVolume (PV) 和 PersistentVolumeClaim (PVC) 来确保数据的持久性。 mysql-pv.yaml&#xff1a; apiVersion: v1 kind: PersistentVolume metadata:name: mysql-pv-volume spec:cap…

Docker和DockerCompose基础教程及安装教程

Docker的应用场景 Web 应用的自动化打包和发布。自动化测试和持续集成、发布。在服务型环境中部署和调整数据库或其他的后台应用。从头编译或者扩展现有的 OpenShift 或 Cloud Foundry 平台来搭建自己的 PaaS 环境。 CentOS Docker 安装 使用官方安装脚本自动安装 安装命令…

网络安全等级保护—定级

&#x1f345; 点击文末小卡片 &#xff0c;免费获取网络安全全套资料&#xff0c;资料在手&#xff0c;涨薪更快 网络安全等级保护五个保护等级 五个保护等级 受侵害的客体 对客体的侵害程度 一般损害 严重损害 特别严重损害 公民、法人和其他组织的合法权益 第一级 第二级 …

macos 程序 运行

sudo xattr -r -d com.apple.quarantine [/Applications/Name]使用stow 管理配置文件

UVC for USBCamera in Android

基于UVC 协议&#xff0c;完成USBCamera 开发 文章目录 一、目的&#xff1a;二、USBCamera 技术实现方案难点 三、误区&#xff1a;四、基础补充、资源参考架构图了解Camera相关专栏零散知识了解部分相机源码参考&#xff0c;学习API使用&#xff0c;梳理流程&#xff0c;偏应…

Docker 安装 Nacos 2.1.1(单机版)

一、拉取镜像 docker pull nacos/nacos-server:v2.1.1 二、新建数据库 官网上下载 对应版本的 nacos zip 包&#xff0c;在 nacos\conf 目录下有 mysql脚本&#xff1a; 新建一个数据库 nacos_config&#xff0c;在数据库中依次执行 nacos-mysql.sql、1.4.0-ipv6_support-up…

网络安全数据富化 网络数据安全处理规范

本文件规定了网络运营者开展网络数据收集、存储、使用、加工、传输、提供、公开等数据处理的安全 技术与管理要求。 本文件适用于网络运营者规范网络数据处理,以及监管部门、第三方评估机构对网络数据处理进行 监督管理和评估。 部分术语和定义 数据&#xff08;data&#x…

深入理解 C 语言函数的定义

在 C 语言的编程世界里&#xff0c;函数是构建复杂程序的基石。理解函数的定义与运用&#xff0c;对于编写高效、可维护的代码至关重要。​ 函数定义的基本概念​ 函数是一组执行特定任务的代码块。它将一个复杂的问题分解为一个个小的、可管理的部分&#xff0c;提高了代码的…

SQL注入练习场:PHPStudy+SQLI-LABS靶场搭建教程(零基础友好版)

注意&#xff1a;文中涉及演示均为模拟测试&#xff0c;切勿用于真实环境&#xff0c;任何未授权测试都是违法行为&#xff01; 一、环境准备 下载PHPStudy 官网下载地址&#xff1a;https://www.xp.cn/php-study&#xff08;选择Windows版&#xff09; 安装时建议选择自定…

WordPress报502错误问题解决-php-fpm-84.service loaded failed failed LSB: starts php-fpm

文章目录 问题描述问题排查问题解决 问题描述 服务器环境&#xff1a; php&#xff1a;8.4MySQL&#xff1a;8.0Nginx&#xff1a;1.26.2 在访问站点时&#xff0c;一直报502&#xff0c;而两天前还能正常访问。 问题排查 导致502的问题很多&#xff0c;比如站点访问量太大…

uniapp 微信小程序 升级 uniad插件版本号

问题描述&#xff1a; 每次提交代码升级的时候会弹窗提示&#xff1a;uniad插件版本太低… 解决办法 一、使用微信小程序开发工具点击右上角 查看到最新版本&#xff1a;1.3.4 二、在app.json中改为最新的版本即可 "uni-ad": {"version": "1.3.4&q…

使用Dockerfile打包java项目生成镜像部署到Linux_java项目打docker镜像的dockerfile

比起容器、镜像来说&#xff0c;Dockerfile 非常普通&#xff0c;它就是一个纯文本&#xff0c;里面记录了一系列的构建指令&#xff0c;比如选择基础镜像、拷贝文件、运行脚本等等&#xff0c;每个指令都会生成一个 Layer&#xff0c;而 Docker 顺序执行这个文件里的所有步骤&…