写OSPF实验报告,最怕的不是命令敲不对,而是报告写完经不起一句追问:为什么邻居是Full就代表正常?为什么R2上能看到Type-3的LSA?为什么我配置了汇总但路由表里没反应?这篇东西就把我在OSPF实验里踩过的坑、验证过的命令、整理好的排错思路全部摊开,给要做同类实验或者正在准备认证考试的人一份能直接照着复现、同时也能讲清原理的完整过程。
文章不会只堆命令,重点放在三个地方:实验拓扑为什么这么设计,配置之后每一步应该看到什么,出了问题怎么快速定位。无论你是在实验室里用真机、模拟器,还是准备写一份能拿得出手的实验报告,这套流程都适用。
1. OSPF实验的目标与拓扑设计
1.1 实验目标:不只是把网打通
我见过太多人做OSPF实验,目标就一句话“让三台路由器能互相ping通”。这个目标不是错,但太浅了。OSPF实验报告真正要证明的,是你对链路状态协议的理解,而不是连通性本身。ping通只能说明路由表里有条目,但路由条目是怎么来的、通过哪种LSA学到的、为什么路径是这条而不是那条,这些才是实验报告应该回答的问题。
所以我在设计实验时,会把目标拆成四层:
- 掌握OSPF邻居建立过程,能解释从Down到Full每个状态的意义。
- 理解区域(Area)的作用,能够描述骨干区域与非骨干区域的关系。
- 能够通过查看LSDB和路由表,区分Router LSA、Network LSA、Summary LSA。
- 掌握ABR上的区域间路由汇总配置,并验证汇总前后的路由表变化。
这四层目标从“能配”到“能讲”,覆盖了OSPF学习中最核心的知识点。按这个目标去做实验,报告内容自然充实,不会出现“全篇都是配置命令但没有任何分析”的问题。
1.2 拓扑设计:三台路由器、两个区域,为什么这么搭
实验拓扑不追求复杂,但也不能简单到只有两台路由器直连。两台设备只能演示邻居建立,体现不出OSPF作为链路状态协议的价值。我用的是三台路由器、两个区域的经典结构:
- R1和R2位于骨干区域Area 0。
- R2和R3位于非骨干区域Area 1。
- R2同时连接两个区域,自然成为ABR(区域边界路由器)。
这个拓扑的精妙之处在于,R3所在区域的任何路由要想进入Area 0,都必须经过R2这个ABR转换。这样你就能在实验中实实在在看到LSA类型的变化:R3在Area 1里产生的Router LSA,到了R2上会被转换成Summary LSA(Type-3),然后再通告给R1。如果没有这个ABR,你永远只能看到LSA 1和LSA 2,对OSPF的理解就缺了一大块。
有人会问,那要不要加第四条链路模拟ASBR和外部路由?我的建议是:基础实验先不要。LSA 4和LSA 5可以放在进阶实验里单独做,否则报告内容太多,反而讲不透。一次实验解决一个核心问题,这是做实验报告的基本准则。
接口和地址规划如下表:
| 设备 | 接口 | IP地址 | OSPF区域 | 说明 |
|---|---|---|---|---|
| R1 | GigabitEthernet0/0 | 10.0.12.1/24 | Area 0 | 与R2互联链路 |
| R1 | Loopback0 | 10.0.1.1/32 | Area 0 | 模拟业务网段 |
| R2 | GigabitEthernet0/0 | 10.0.12.2/24 | Area 0 | 与R1互联链路 |
| R2 | GigabitEthernet0/1 | 10.0.23.2/24 | Area 1 | 与R3互联链路 |
| R2 | Loopback0 | 10.0.2.2/32 | Area 0 | 模拟业务网段 |
| R3 | GigabitEthernet0/0 | 10.0.23.3/24 | Area 1 | 与R2互联链路 |
| R3 | Loopback1 | 10.0.3.1/32 | Area 1 | 用于区域汇总测试 |
| R3 | Loopback2 | 10.0.3.2/32 | Area 1 | 用于区域汇总测试 |
| R3 | Loopback3 | 10.0.3.3/32 | Area 1 | 用于区域汇总测试 |
地址规划上有两个细节值得说明。第一,环回口我统一用/32掩码,因为OSPF对环回口的默认处理方式就是通告为/32,哪怕你配置了/24,它在OSPF里依然以主机路由的形式出现。与其让初学者对着“明明配了/24却看到/32”的现象发懵,不如直接按/32来配。第二,我在R3上规划了三个环回口地址10.0.3.1、10.0.3.2、10.0.3.3,它们都属于10.0.3.0/24这个网段,这是为后面的区域间路由汇总准备的。没有这三个地址,汇总实验就做不起来。
2. 基础配置与邻居建立过程
2.1 配置OSPF:用接口方式宣告,省心一半
OSPF的宣告方式主要有两种:一种是传统的network命令,一种是接口下的ip ospf配置。很多教材还在用network方式,但实际配置我更推荐接口方式,尤其是实验涉及多区域的时候。接口方式的好处是,你不需要去计算反掩码,也不会因为network语句匹配了多余接口而把不该进OSPF的网段宣告进去。
三台设备的核心配置如下。R1的配置:
interface GigabitEthernet0/0 ip address 10.0.12.1 255.255.255.0 interface Loopback0 ip address 10.0.1.1 255.255.255.255 router ospf 1 router-id 1.1.1.1 interface GigabitEthernet0/0 ip ospf 1 area 0 interface Loopback0 ip ospf 1 area 0R2的配置:
interface GigabitEthernet0/0 ip address 10.0.12.2 255.255.255.0 interface GigabitEthernet0/1 ip address 10.0.23.2 255.255.255.0 interface Loopback0 ip address 10.0.2.2 255.255.255.255 router ospf 1 router-id 2.2.2.2 interface GigabitEthernet0/0 ip ospf 1 area 0 interface GigabitEthernet0/1 ip ospf 1 area 1 interface Loopback0 ip ospf 1 area 0R3的配置:
interface GigabitEthernet0/0 ip address 10.0.23.3 255.255.255.0 interface Loopback1 ip address 10.0.3.1 255.255.255.255 ip ospf 1 area 1 interface Loopback2 ip address 10.0.3.2 255.255.255.255 ip ospf 1 area 1 interface Loopback3 ip address 10.0.3.3 255.255.255.255 ip ospf 1 area 1 router ospf 1 router-id 3.3.3.3这里有几个容易被忽略的配置点:
- 进程号
1只在本地有意义,R1用process 1,R2用process 2,两者依然能建立邻居。但实验里我会统一用1,减少干扰因素。 - 显式配置
router-id是必须养成的习惯。如果不配,路由器会从环回口或物理接口IP里选最大的作为Router-ID。一旦接口地址变化,Router-ID就变,所有邻居关系会被重置,这种故障极其隐蔽,抓包都很难一眼看出来。 - 环回口用
ip ospf 1 area 1宣告时,它会被当作OSPF接口参与路由计算,但默认网络类型是环回口专用类型,通告为/32。对实验来说这是预期行为。
配置完成后,不要急着往下走,先看邻居状态。在R2上执行:
show ip ospf neighbor如果配置没问题,输出里应该能看到R1和R3两个邻居,状态为FULL/DR或FULL/BDR。如果只看到一个甚至一个都没有,说明Hello包交互有问题,原因多半是接口没有正确宣告、区域号不一致、或者Router-ID冲突。具体排错放到后面第4节细说。
2.2 邻居状态机:从Down到Full,到底发生了什么
OSPF的邻居状态机是实验报告里最值得写的部分。很多人只知道看最终状态是不是Full,却说不清中间状态的意义,这样报告写出来是空心的。
完整的邻居状态是:Down、Attempt、Init、2-Way、Exstart、Exchange、Loading、Full。实验里最常看到的是Down、Init、2-Way、Exstart、Exchange、Loading、Full这几个。我用一个生活化的类比解释:
- Down:两个人还没打过招呼,谁也不知道对面存在。
- Init:我收到过你的消息,但不确定你是不是收到了我的消息。就像你在群里发了“你好”,看到对方发了消息,但不确定对方看没看到你的。
- 2-Way:双方都确认了彼此存在,互相收到了对方的Hello包,里面包含各自的Router-ID。这个状态说明邻居关系已经建立,但还没开始交换路由信息。
- Exstart:开始选“谁先说”。接口或路由器会协商主从关系,确定初始的序列号。这一步容易出现MTU不匹配的问题,我在第4节会专门讲。
- Exchange:交换数据库描述包,相当于互相报目录,说“我有这些LSA”。
- Loading:对照目录发现自己缺少某些LSA,向对方发送链路状态请求,对方回应链路状态更新。这一步才是真正下载路由信息的过程。
- Full:所有LSA同步完成,邻接关系完全建立。
注意一个容易搞混的点:2-Way和Full都是正常状态。在广播多路访问网络中,非DR/BDR路由器之间会停在2-Way状态,这是设计如此,不是故障。如果你在以太网环境下看到一堆2-Way邻居,完全不用紧张。只有接口的邻居状态异常卡在Init或者Exstart,才需要排查。
2.3 DR和BDR:广播链路绕不开的机制
三台路由器我用的是以太网接口互联,所以邻居状态输出里会出现DR和BDR的标记。这就是OSPF在广播多路访问网络上的特殊之处:同一个网段里所有路由器如果两两建立邻接关系并交换LSA,会产生大量冗余报文。解决办法是选出一个DR和一个BDR,其他路由器只和DR、BDR建立Full邻接关系,路由器之间保持2-Way即可。
DR和BDR的选举规则是:优先比较接口优先级,默认值是1,越大越优先;如果优先级相同,则比较Router-ID,越大越优。特别注意,选举是非抢占的。也就是说,已经存在的DR不会因为后来加入一台Router-ID更大的路由器就自动让位,除非DR的接口故障或者OSPF进程重启。这个特性在实验验证时经常被误解,有人为了看选举变化,往拓扑里加了一台新设备,发现DR没变,以为配置错了。实际上这不是错误,是协议机制。
R1、R2、R3之间的两条链路都是广播类型,所以每条链路上都会选举各自的DR。如果你不想看到DR/BDR,避免涉及到选举问题,可以在接口下把网络类型改成点到点:
interface GigabitEthernet0/0 ip ospf network point-to-point改成点到点之后,OSPF就不做DR/BDR选举,邻居状态直接建立到Full,配置和排查都更简单。实验里按需使用,我建议至少在一个链路上保留默认的广播类型,因为观察DR/BDR的选举过程是理解OSPF网络类型的好机会。
3. LSA类型与区域间路由
3.1 从LSDB看懂OSPF在“想什么”
链路状态协议和距离矢量协议最大的区别在于,OSPF路由器维护的不是一张简单的路由表,而是一份链路状态数据库LSDB。路由表只是路由器根据自己的SPF算法从LSDB里算出来的结果。所以,排错的时候只看路由表是不够的,要看LSDB里的LSA是不是完整、合理。
配置完成后,在R2上执行:
show ip ospf databaseArea 0部分的输出大致如下:
Router Link States (Area 0) Link ID ADV Router Age Seq# Link count 1.1.1.1 1.1.1.1 123 0x80000003 2 2.2.2.2 2.2.2.2 456 0x80000004 3 Summary Net Link States (Area 0) Link ID ADV Router Age Seq# 10.0.3.0 2.2.2.2 100 0x80000001Router Link States这一部分就是Router LSA,也就是LSA 1。每一台路由器都会在它所属的区域里产生一条Router LSA,描述自己直连的链路。比如R1的Router LSA里,会描述10.0.12.0/24和10.0.1.1/32这两个直连网段。R2作为ABR,同时属于Area 0和Area 1,所以它会在两个区域里分别产生Router LSA。
Summary Net Link States就是LSA 3。注意看Link ID是10.0.3.0,ADV Router是2.2.2.2。这条LSA说明Area 0里的路由器已经知道,在Area 1那边有一个10.0.3.0/24的网段可以经由R2到达。这个10.0.3.0/24网段为什么以汇总形式出现,而不是三条/32主机路由?因为我配置了区域间的路由汇总。如果不配,这里会显示10.0.3.1、10.0.3.2、10.0.3.3三条独立的Summary LSA。
这里把LSA类型简单归纳一下:
| LSA类型 | 名称 | 谁产生 | 传递范围 | 描述内容 |
|---|---|---|---|---|
| Type 1 | Router LSA | 每台路由器 | 所在区域内部 | 路由器直连链路状态 |
| Type 2 | Network LSA | DR | 所在区域内部 | 广播网络上所有连接路由器的信息 |
| Type 3 | Summary LSA | ABR | 跨区域传递 | 区域间路由摘要 |
| Type 4 | ASBR Summary LSA | ABR | 跨区域传递 | ASBR的位置信息 |
| Type 5 | External LSA | ASBR | 整个OSPF域 | 外部路由信息 |
用类比来记:Router LSA是个人简历,每台路由器都有一份,内容是自己有哪些直连网段;Network LSA是部门通讯录,由DR记录广播链路上都有哪些人;Summary LSA是总部向分部发的简报,说“那个区域里有什么网段,你们从我这里走就行”。
3.2 ABR与区域间路由的传递逻辑
R2是ABR,它把Area 1的拓扑信息和路由信息汇总后,以Type-3 LSA的形式通告进Area 0。这个“汇总”不是指route summarization,而是指“把区域内复杂链路信息简化为路由条目”。换句话说,Area 0里的R1不需要知道R3的拓扑细节,只需要知道“去10.0.3.0/24,下一跳是R2”就足够了。
这也回答了为什么OSPF必须有一个Area 0作为骨干区域。所有非骨干区域的路由,都必须经过ABR把Type-1/2 LSA转换成Type-3 LSA,再通过骨干区域进行传递。如果某个区域不直接连接Area 0,这个转换就无法完成。实验里最容易犯的错误是:把R1和R2放在Area 1,R2和R3放在Area 0,或者干脆三台路由器都在不同区域,结果R1和R3之间始终学不到路由。这不是OSPF没起来,而是违背了区域设计的基本规则。
要在R2上确认区域间路由是否正常,可以用:
show ip route ospfR2上应该能看到去往10.0.3.1/32、10.0.3.2/32、10.0.3.3/32的路由(在配置汇总前),或者看到去往10.0.3.0/24的路由(配置汇总后)。同时R1上也能看到同样的路由,只是下一跳指向10.0.12.2,因为R1到达那些网段必须经过R2这个ABR。
3.3 区域间路由汇总实操
区域间路由汇总可以缩减LSDB规模和路由表条目,是做OSPF实验时非常值得演示的内容。实验前提是R3上有多个连续的/32前缀,我在地址规划里安排了10.0.3.1、10.0.3.2、10.0.3.3,它们正好落在10.0.3.0/24网段内。
在没有汇总的情况下,R1的路由表里会有三条OSPF区域间路由:
O IA 10.0.3.1/32 [110/2] via 10.0.12.2, GigabitEthernet0/0 O IA 10.0.3.2/32 [110/2] via 10.0.12.2, GigabitEthernet0/0 O IA 10.0.3.3/32 [110/2] via 10.0.12.2, GigabitEthernet0/0现在到R2的OSPF进程下配置汇总:
router ospf 1 area 1 range 10.0.3.0 255.255.255.0配置之后再回到R1查看路由表,会发现三条/32路由变成了一条:
O IA 10.0.3.0/24 [110/2] via 10.0.12.2, GigabitEthernet0/0这就是区域间汇总的效果。注意,这个命令只需要在ABR上配置,也就是在R2上配置,而不是在R1或R3上配置。area 1 range表示把Area 1内的路由按10.0.3.0/24这个前缀进行聚合。
不过,汇总不是没有代价。聚合之后,R1只知道去10.0.3.0/24这个网段走R2,但不知道网段内部有哪些更精细的路由。如果Area 1内部因为链路故障只剩下一部分路由可达,ABR依然会通告聚合路由,这可能导致流量被送到一个实际上并不完全可达的网段,出现次优路径甚至黑洞。所以在生产环境里配置汇总前,一定要确认企业内部网段规划和故障隔离需求。
4. 验证命令与排错实战
4.1 一套可复用的验证路径
实验做完了,验证不是随便敲一条ping就结束。我习惯按照“邻居→接口→数据库→路由表→连通性”的顺序逐步验证,每一步都能对上前面环节的预期。
核心验证命令如下:
| 命令 | 验证目标 | 重点看什么 |
|---|---|---|
| show ip ospf neighbor | 邻居关系是否建立 | Neighbor ID、State、Dead Time |
| show ip ospf interface | 接口是否参与OSPF | 接口所属区域、网络类型、计时器 |
| show ip ospf database | LSDB是否完整 | LSA类型、ADV Router、Link ID |
| show ip route ospf | OSPF路由是否安装 | 路由前缀、管理距离、下一跳 |
| show ip protocols | OSPF进程参数 | Router-ID、区域配置、汇总配置 |
| ping / traceroute | 数据面连通性 | 端到端是否可达、路径是否符合预期 |
以R2为例,一份完整的邻居验证输出:
R2# show ip ospf neighbor Neighbor ID Pri State Dead Time Address Interface 1.1.1.1 1 FULL/DR 00:00:39 10.0.12.1 GigabitEthernet0/0 3.3.3.3 1 FULL/BDR 00:00:32 10.0.23.3 GigabitEthernet0/1邻居ID分别是R1和R3的Router-ID,状态都是Full,Dead Time在正常倒计时。第二条邻居的接口是GigabitEthernet0/1,对应R2连接R3的Area 1链路。看到这些信息,基本可以判定控制平面正常。接下来再看R2的OSPF路由:
R2# show ip route ospf O 10.0.1.1 [110/2] via 10.0.12.1, GigabitEthernet0/0 O IA 10.0.3.0/24 [110/2] via 10.0.23.3, GigabitEthernet0/1注意O和O IA的区别。O表示区域内路由,O IA表示区域间路由。R1的环回口10.0.1.1与R2同处Area 0,所以路由表中标记为O;R3的网段在Area 1,经R2这个ABR传过来,所以标记为O IA。这个细节写报告时一定要点出来,它是判断你是否真正理解区域间路由的有力证据。
最后用ping验证数据面。比如在R1上ping R3的三个环回口:
ping 10.0.3.1 ping 10.0.3.2 ping 10.0.3.3能通,说明从R1到R3区域的转发路径没有问题。
4.2 常见问题自查表
实验过程中最容易踩的坑,我整理成了一张自查表,照着查比盲目试命令效率高得多。
| 现象 | 原因 | 解决办法 |
|---|---|---|
| 邻居状态一直卡在Init | 收到的Hello包里区域ID不匹配,或接口没有启用OSPF | 检查两端的ip ospf区域配置是否一致 |
| 邻居状态卡在Exstart/Exchange | 两端接口MTU不一致,Database Description包过大被丢弃 | 统一接口MTU,或在接口下配置忽略MTU检查 |
| 邻居反复Down然后重新起来 | Hello间隔或Dead间隔不一致,Dead Timer超时 | 查看双方show ip ospf interface,统一计时器 |
| R1学不到R3的路由 | Area 1没有经过ABR连接Area 0 | 确认R2是ABR,且R2同时宣告了Area 0和Area 1接口 |
| 路由表里出现多条去往同一网段的路径 | 区域间和区域内同时存在路由 | 确认OSPF区域内路由优先于区域间路由,无需干预 |
| 配置汇总后路由表没有任何变化 | 在非ABR上配置了area x range,或汇总前缀不匹配 | 确认配置在ABR上,并且被汇总网段落在前缀范围内 |
表格之外,我想单独强调两个高频问题,因为它们在实验报告里被问到的概率极高。
第一个是MTU问题。OSPF在设计上要求两台路由器之间的MTU一致,因为在Exchange阶段发送的Database Description包如果超过了接口MTU,会被直接丢弃。在实验环境里,两台设备的以太网接口默认MTU通常是1500,一般不会出问题。但如果你在模拟链路中手动修改了某一端接口的MTU,或者用隧道接口做实验,就非常容易出现邻居卡在Exstart的诡异现象。排查办法很简单:在两端分别看接口MTU,然后统一数值。
第二个是Router-ID冲突。假设你在R2上显式配置了router-id 3.3.3.3,而R3的Router-ID也是3.3.3.3,那么R1会同时收到来自两个不同接口的、Router-ID相同的Hello包。OSPF会认为这是同一台路由器,邻居关系无法正常建立。实验时一定要养成用show ip ospf查看Router-ID的习惯,确保每台设备唯一。
4.3 抓包验证:用实锤数据说话
如果实验环境允许,强烈建议在R2与R3互联的链路上用抓包工具看一次OSPF报文。抓包的目的不是摆拍,而是让你直观看到三种关键报文:
- Hello包:周期性发送,默认10秒一次,里面包含Router-ID、Hello间隔、Dead间隔、邻居列表。
- Database Description包:在Exchange阶段发送,携带LSA报头列表,是后面Loading阶段的“购物清单”。
- Link State Update包:真正包含完整LSA数据,承载链路状态信息。
抓包时有一个非常直观的体验:广播链路上所有路由器都会周期性发送Hello包,但你不会看到每两台路由器之间都传输LSU。因为有了DR机制,非DR路由器只和DR、BDR交换LSA,其他路由器之间的通信仅限于Hello包层面。这个现象在抓包结果里非常清晰,比任何文字描述都有说服力。
写实验报告时,可以把抓包结果的关键字段截图放进去,比如Hello包里的Neighbor列表、LSA的Link ID和ADV Router,这些是“实锤数据”,能证明你的实验不是照着配置敲完就算了,而是真正理解了报文交互。
5. 实验报告的组织与呈现技巧
5.1 报告结构:让每一步都有据可查
一份好的OSPF实验报告不是流水账,更不是把show命令输出全部粘贴一遍。我常用的报告结构是:实验目的、拓扑与地址规划、配置过程、验证记录、数据分析、问题与结论。其中,“数据分析”和“问题与结论”是拉开差距的两个部分。
数据分析部分要针对关键验证输出做解读,不能只贴输出不加解释。比如你贴了show ip ospf neighbor的输出,就要说明为什么状态是FULL/DR,为什么对方是BDR而不是DR,这背后和接口优先级、Router-ID的关系是什么。你贴了show ip route ospf的输出,就要说明为什么某条路由是O而另一条是O IA,这能证明你理解区域间路由传递逻辑。
问题与结论部分,不要只写“实验成功”。实验过程中遇到的每一个问题,都应该按照“现象描述→排查过程→根因分析→解决办法”的格式记录下来。这样的报告,无论交给老师还是领导,都能体现完整的排错能力。
5.2 数据记录:把验证输出变成证据链
我在反复做实验之后养成了一个习惯:每敲完一段配置,就立刻执行对应的验证命令,把输出保存下来。这不是多此一举,而是在构建证据链。配置是“你做了什么”,验证输出是“系统因此产生了什么结果”,两者一一对应,才是完整的实验记录。
具体做法很小:新建一个实验记录目录,按设备或按步骤给文件命名。比如保存R2的邻居状态、保存R1的OSPF路由表、保存汇总前后的LSDB对比。写报告的时候,直接引用这些记录,不用重新敲命令,也不会出现“配置和输出对不上”的问题。
还有一个细节:拓扑图必须和实际配置一致。我在批改类似实验报告时经常发现,文字描述里写的是Area 0和Area 1,拓扑图却只画了两台路由器;或者图里标了地址10.0.0.0/24,配置里却是10.0.1.0/24。这种低级错误会严重拉低整份报告的可靠性。画图时,务必把接口IP、区域编号、设备Router-ID全部标清楚,并且和配置文件逐一核对。
5.3 让报告经得起追问的三个锦囊
最后分享三个让实验报告“升值”的技巧。
第一,在报告里写出“预期结果”和“实际结果”的对比。比如配置汇总之前,预期R1路由表里有三条/32路由,实际也是三条;配置汇总之后,预期变成一条/24路由,实际变成了一条。这种前后对比比单纯贴输出更有说服力。
第二,把默认参数写清楚。实验里广播链路默认Hello间隔是10秒、Dead间隔是40秒,这些参数可以通过show ip ospf interface看到。报告里把这些参数记录下来,并解释如果一端改了Dead间隔会发生什么,说明你对协议细节有把控。
第三,主动讨论“如果发生变化会怎样”。比如,“如果R1的接口优先级调为0,它还能参与DR选举吗?”“如果Area 1不是经过R2而是经过一台非ABR设备连接Area 0,R3的路由能传到Area 0吗?”这类问题不一定都要做实验验证,但在报告的分析部分写上一两句,能明显看出你是在思考协议,而不是背配置。
我在实际做这个实验时,最有感触的一点是:OSPF实验报告的价值不在配置正确,而在你能讲清楚为什么这样配。刚开始我也犯过“邻居Full就急着写报告”的毛病,结果一配区域间汇总,R1立刻学不到R3的环回路由,整份报告废掉。后来我养成一个习惯:每敲一条配置,马上用show命令验证,并把输出按步骤归档。这个多花不了几分钟的习惯,帮我省下的排错时间远比敲命令的时间多。希望这份实验整理,也能让你少走这些弯路。