
简介一份面向南京大学2024年计算机网络课程的实验资料包适合正在修读该课程或自学网络原理的本科生、研究生作为实验与复习参考。资源围绕七次递进式实验展开从数据链路层的自学习交换、IP路由转发到传输层的可靠传输、TCP/UDP编程再到防火墙规则、安全策略与简单网络服务实现基本覆盖本科计算机网络课程核心知识点同时配有README实验指南、Mininet拓扑脚本、测试样例和pcap抓包文件方便对照理解实验预期与实际运行结果。压缩包共38个文件以Python脚本为主29个分别承担交换、路由、防火墙与传输层协议的实现和测试另有6个txt参数与配置、1个markdown说明文档、1个shell启动脚本和1个pcap网络抓包数据整体仅39KB结构紧凑而完整。当前已有159人学习使用适合需要快速搭建实验环境、完成实验报告或根据pcap与测试脚本复盘关键协议细节的同学。1. 一份能直接复现的南京大学计网实验包从 Mininet 到完整协议栈如果你正在准备计算机网络课程的期末复习、考研复试或者面试手头最缺的往往不是教材而是一套能真正跑起来的实验代码。这份南京大学 2024 年计算机网络课程的实验包包含了 lab_1 到 lab_7 七个实验的完整源码、测试脚本和 Mininet 拓扑启动脚本覆盖了从集线器、交换机、路由器到可靠传输协议、防火墙和 Web 服务器的全部核心知识点。它不是那种只有 PDF 报告的空壳资源而是每一行代码都能直接运行、每一个测试文件都能验证结果的实操项目。对于正在学计网的学生、想补实验经验的考研党、以及需要快速搭建网络实验环境的从业者来说这套实验的价值在于你不需要从零设计实验拓扑也不需要自己造轮子写测试框架直接在 Mininet 里跑起来就能看到数据包转发的完整过程。当然这套实验的坑也不少从解压到跑通每一层都有值得记录的血泪经验。2. 实验包全貌与运行环境七个 lab 的依赖关系和复现成本2.1 七个 lab 在课程知识体系中的实际位置打开压缩包后第一件事不是急着解压运行而是先看清楚 README.md 和目录结构。这个包里的 lab_1 到 lab_7 是按照计算机网络课程的教学进度排布的每两个 lab 之间都有明确的前置依赖关系。lab_1 是 myhub.py对应数据链路层的集线器实验核心是理解物理层和数据链路层的广播机制。lab_2 是 myswitch.py 以及它的变体 myswitch_lru.py、myswitch_to.py对应交换机的自学习算法和 MAC 地址表的维护策略。lab_3、lab_4、lab_5 都是 myrouter.py只是配套的测试文件和转发表不同这三个 lab 实际上是一个递进序列从静态路由到动态路由再到完整的路由器测试验证。lab_6 是整个实验包中最重头的部分包含了 blaster.py、blastee.py、middlebox.py 三个程序以及 blaster_params.txt、blastee_params.txt、middlebox_params.txt 三个参数文件。这是可靠数据传输协议实验模拟的是 TCP 可靠传输的核心机制需要在不可靠的信道上实现可靠的数据交付。lab_7 是防火墙实验包含 firewall.py 和 firewall_rules.txt同时还有一个 start_webserver.sh 和 www 目录这说明 lab_7 要求实现一个带防火墙过滤规则的 Web 服务。每个 lab 目录下都有 start_mininet.py 脚本这一点非常关键。Mininet 是一个网络仿真工具它能在单台 Linux 主机上创建出一组虚拟的交换机、路由器和主机然后通过虚拟网卡把它们连接起来整个环境都是在用户态运行的。这意味着你不需要物理路由器也不需要在虚拟机里搭多台机器只要一台能装 Mininet 的 Linux 主机就能完成全部实验。2.2 Mininet 环境的搭建与四个原始坑位在开始跑第一个实验之前需要先确认环境是否就绪。Mininet 的安装方式在不同发行版上不一样Ubuntu 系可以用 apt 安装Fedora 系可以用 dnf但无论哪种方式装完之后都要验证两个东西sudo mn --test pingall 能通以及 Python 环境能正常导入 mininet 模块。# 验证 Mininet 是否安装成功Ubuntu 20.04 及以上 sudo apt update sudo apt install -y mininet python3-pip sudo mn --test pingall # 输出结果中 0% packet loss 说明 Mininet 基本可用这段代码的逻辑很简单先更新包索引然后安装 Mininet 和 pip最后用 Mininet 自带的 pingall 测试来验证环境是否正常。pingall 这个命令会创建一台交换机、两台主机的默认拓扑然后测试两台主机之间能否互通。如果这一步就报错大概率是内核模块没有加载需要检查 openvswitch 服务是否启动或者干脆重启一次系统让内核模块生效。装好 Mininet 之后还有几个容易掉进去的坑需要提前注意。第一个坑是 Python 版本问题这套实验的代码基于 Python 2/3 兼容的写法但 Mininet 的控制器脚本对 Python 3 的支持更友好我建议直接用 Python 3.8 以上的版本跑不要折腾 Python 2 环境。第二个坑是 sudo 权限Mininet 创建虚拟网络需要 root 权限所以 start_mininet.py 必须用 sudo 执行否则会报权限不足。第三个坑是端口冲突如果在跑实验之前有别的程序占用了 Mininet 需要的虚拟端口拓扑就起不来最常见的元凶是之前残留的 mininet 进程用 sudo mn -c 清理一下就好。第四个坑是防火墙干扰实验过程中抓包工具和防火墙规则会产生冲突我当时因为开着系统自带的防火墙导致实验主机之间 ping 不通白白浪费了半小时排查。提示每次跑新实验前先执行 sudo mn -c 清理残留进程这个命令会清掉上次实验没正常退出的虚拟网络能避免大量莫名其妙的异常。3. 自学习与转发从 hub 到 switch 再到 router 的演进逻辑3.1 lab_1 hub广播风暴的第一课lab_1 的 myhub.py 是整个实验包的起点它的功能是把收到的数据帧从除了入端口以外的所有端口广播出去。这个实验虽然简单但它是理解后续所有转发设备的基础——你必须先明白广播为什么是低效的才能理解交换机为什么要做自学习。# myhub.py 的核心转发逻辑实验要点版本 class Hub: def handle_packet(self, packet, in_port): # 对于 hub 来说不需要学习 MAC 地址也不需要查表 # 只需要把包从其他所有端口转发出去 for port in self.ports: if port ! in_port: self.send_packet(packet, port)这段代码的逻辑是遍历所有端口除了收到数据包的端口之外把原始数据包原封不动地发出去。hub 不关心数据包的内容也不关心 MAC 地址它只做广播转发。这样做的后果是如果网络中有 N 台主机每个数据帧都会被复制 N-1 份当网络规模变大时广播流量会指数级增长最终形成广播风暴。lab_1 目录下的 lab_1.pcap 是实验要求的抓包结果文件你可以用 Wireshark 打开看看。实际跑这个实验时我在三台主机的拓扑上发送了一个 ping 包用 tcpdump 抓包发现一个 ARP 请求会被 hub 广播到所有端口然后所有主机都会收到这个与自己无关的请求。这个现象直接印证了 hub 的缺陷——它在数据链路层上没有任何智能只是无差别广播。3.2 lab_2 switchMAC 自学习与 LRU 淘汰lab_2 的 myswitch.py 比 hub 进化了一大步它维护了一张 MAC 地址表能够根据数据帧的源 MAC 地址学习端口映射关系然后根据目的 MAC 地址精确转发。这个实验包提供了一个基础版本、一个 LRU 淘汰版本myswitch_lru.py和一个超时版本myswitch_to.py三个版本的区别在于 MAC 地址表的维护策略。# myswitch.py 的 MAC 自学习核心逻辑 class Switch: def __init__(self): # mac_table 记录了 MAC 地址到端口的映射 # 格式{mac_address: port_number} self.mac_table {} def handle_packet(self, packet, in_port): # 1. 学习阶段把源 MAC 和入端口记录到表中 src_mac packet.get_src_mac() self.mac_table[src_mac] in_port # 2. 转发阶段查目的 MAC 是否已知 dst_mac packet.get_dst_mac() if dst_mac in self.mac_table: # 已知则单播转发到对应端口 self.send_packet(packet, self.mac_table[dst_mac]) else: # 未知则洪泛到所有端口hub 行为 for port in self.ports: if port ! in_port: self.send_packet(packet, port)这段代码的逻辑分两步先学习源 MAC 地址与入端口的对应关系再查目的 MAC 地址决定转发策略。关键参数是 mac_table 的大小和淘汰策略。基础版本不限制表的大小但实际网络环境中 MAC 地址表容量有限所以 myswitch_lru.py 实现了 LRU最久未使用淘汰算法当表满时淘汰最久没有刷新的条目myswitch_to.py 则实现了超时机制超过一定时间没有出现的 MAC 地址会被自动清除。从实验角度看lab_2 的测试脚本 mytests_traffic.py 和 myswitch_traffic.py 是用来模拟真实流量模式的mytests_lru.py 专门用来验证 LRU 淘汰逻辑。我跑这个实验时写了一个测试让主机 A 和主机 B 通信然后让主机 C 不断发包观察 MAC 地址表的变化。当表容量设为 2 时主机 C 的流量会把主机 A 的条目挤掉这就是 LRU 淘汰的实际效果。这个实验对理解交换机的自学习机制和地址表维护策略非常有帮助尤其是当你后续要做更复杂的网络设备时MAC 表的管理策略直接影响转发性能。3.3 lab_3、lab_4、lab_5 router转发决策、转发表与最长前缀匹配从 lab_3 开始实验难度明显提升三个 lab 都围绕 myrouter.py 展开但它们考察的层次不同。lab_3 是最基础的路由转发lab_4 增加了 forwarding_table.txt 的读取和解析lab_5 则有完整的 routertests.py 测试套件和 forward_table.txt。路由器和交换机最本质的区别在于交换机工作在数据链路层根据 MAC 地址转发路由器工作在网络层根据 IP 地址和转发表做最长前缀匹配转发。# lab_4 myrouter.py 的转发表查找逻辑 class Router: def __init__(self): # 转发表项[(目的网络前缀, 前缀长度, 下一跳 IP, 出端口)] self.routing_table [] self.load_forwarding_table(forwarding_table.txt) def load_forwarding_table(self, filename): # 解析转发表文件每一行格式 # 10.0.0.0 24 192.168.1.1 eth0 with open(filename, r) as f: for line in f: parts line.strip().split() if len(parts) 4: network, prefix_len, next_hop, interface parts self.routing_table.append({ network: network, prefix_len: int(prefix_len), next_hop: next_hop, interface: interface }) def lookup(self, dest_ip): # 最长前缀匹配在转发表中找到最长的匹配前缀 best_match None best_len -1 for entry in self.routing_table: if self._matches(entry, dest_ip): if entry[prefix_len] best_len: best_match entry best_len entry[prefix_len] return best_match这段代码的逻辑是从 forwarding_table.txt 读取转发表项然后对目的 IP 做最长前缀匹配。核心参数是 prefix_len它决定了路由的精确程度。/24 的路由比 /16 的路由更精确所以在查找时要选择前缀长度最长的匹配项。实际实验时我手动修改过 forwarding_table.txt新增了一条默认路由 0.0.0.0/0这样凡是转发表中找不到精确匹配的流量都会走默认路由这也是真实路由器配置中的常见做法。lab_5 比 lab_4 多了一个关键文件 lab5_routertests.py它是一套完整的自动化测试脚本。测试覆盖了几个维度基础转发两个子网互通、未知网络查不到路由时丢弃或走默认路由、TTL 衰减跳数减到 0 时丢弃或回 ICMP 超时。这些测试脚本的价值在于它们给出了路由实验的验收标准你不需要自己猜测实验要求跑一遍测试就能知道实现是否完整。我在跑 lab_5 时发现自己的实现处理了正常转发和 TTL 衰减但没有处理 ICMP 差错报文导致测试在特定用例上报错——这个细节是实验最有价值的考点之一。4. 可靠传输实验blaster、blastee 与 middlebox 的端到端全链路4.1 三个参数文件分别控制什么lab_6 是这套实验包中最完整、最接近实际工程项目的一个实验。它用三个程序模拟了可靠数据传输的完整闭环blaster.py 是发送方负责把数据包发送出去blastee.py 是接收方负责接收数据包并发送确认middlebox.py 则扮演中间路由器的角色模拟网络中的丢包、延迟和乱序。三个参数文件 blaster_params.txt、blastee_params.txt、middlebox_params.txt 分别控制这三个程序的运行参数。# middlebox_params.txt 的典型配置 # 丢包率0.0 - 1.00.1 表示 10% 的包会被丢弃 LOSS_RATE 0.1 # 延迟毫秒每个包在 middlebox 中的模拟排队时间 DELAY_MS 20 # 乱序概率0.0 - 1.00.05 表示 5% 的包会乱序 REORDER_RATE 0.05 # 缓存大小模拟路由器队列的容量 BUFFER_SIZE 10这段配置的逻辑是通过调整丢包率和延迟参数模拟一个不完全可靠的网络环境。我一般会用三组参数跑同一个实验第一组是无丢包无延迟理想情况第二组是 10% 丢包加 20ms 延迟轻度劣化第三组是 30% 丢包加 100ms 延迟重度劣化。每组参数下blaster 的发送行为、重传策略和最终吞吐量完全不同这能直观地看出可靠传输协议的适应性。4.2 middlebox 如何模拟丢包、延迟与乱序middlebox.py 是整个实验的支点它位于 blaster 和 blastee 之间接收 blaster 发出的数据包然后按照参数文件的配置进行处理。丢包是直接丢弃延迟是把包放进缓存队列等待一段时间再发送乱序则是把部分包交换顺序。blaster 和 blastee 都不知道 middlebox 做了什么它们只能通过数据包是否到达、确认是否返回来判断网络状态。# blaster.py 的核心发送数据包并处理超时重传 class Blaster: def __init__(self, params_file): self.window_size 1 # 初始窗口大小为 1即停等协议 self.timeout 0.5 # 超时时间秒 self.seq_num 0 self.packets self.load_file_data() def send_packet(self): # 发送窗口内的所有数据包 for seq in range(self.seq_num, self.seq_num self.window_size): packet self.create_packet(seq) self.send(packet) self.start_timer(seq, self.timeout) def handle_ack(self, ack_seq): # 收到确认后滑动窗口继续发送 if ack_seq self.seq_num: self.seq_num ack_seq self.cancel_timer(ack_seq) self.send_packet() def handle_timeout(self, seq): # 超时未收到确认重传该数据包 self.send_packet(seq) self.start_timer(seq, self.timeout)这段代码是可靠传输协议的标准实现骨架核心参数是 window_size、timeout 和 seq_num它们决定了发送效率和重传策略。window_size 等于 1 时就是停等协议简单但效率低调大 window_size 就是滑动窗口协议效率高但要处理乱序和缓存问题。timeout 的设置是实验中的重点和难点如果设置得太小正常网络延迟也会触发重传导致大量重复数据包如果设置得太大丢包后需要等很久才能发现吞吐量会大幅下降。4.3 流量控制与拥塞表现的取舍lab_6 没有直接要求实现拥塞控制算法但在实际跑实验时你会发现如果不控制发送速率middlebox 的缓存很快会被填满然后持续丢包。我的做法是对 blaster 加上一个发送速率限制比如每秒最多发送 100 个包然后观察不同速率下的吞吐量变化。速率太低时信道利用率不足速率太高时缓存溢出导致丢包率上升只有找到临界速率才能在丢包率可接受的前提下获得最大吞吐量。实验包中的测试文件虽然名字没有像 lab_5 那么直观但 mytests.py 和 start_mininet.py 提供了完整的拓扑和流量控制场景。我在跑实验时发现了一个隐藏考点blastee.py 需要处理重复数据包和乱序数据包如果实现时只按顺序接收一旦遇到乱序就会卡死。正确做法是把收到的包先放入缓存窗口等缺失的包补齐后再向上层交付——这就是 TCP 接收方的经典处理逻辑。运行带参数的实验时我遇到过 blaster 发送数据后卡住的情况排查后发现是 ack_seq 判断用了等号而不是大于号导致重复 ACK 不处理滑动窗口无法前进这个 bug 让我排查了一整个下午。注意middlebox 的 BUFFER_SIZE 参数直接决定了网络的容忍度。把 BUFFER_SIZE 设成 50延迟和丢包都调高后blaster 的表现依然稳定但 BUFFER_SIZE 设成 5 时相同参数下就会出现明显的重传风暴。5. 计网实验避坑手册从解压 ZIP 到 Mininet 与抓包5.1 解压 ZIP 报“伪加密”或损坏先看校验和再谈其他很多从网上下载的课程实验包都有一个特点压缩包本身可能做了加密或伪加密处理。伪加密是指 ZIP 文件头的加密标志被修改解压时会提示输入密码但实际文件内容没有被加密这时候用一些专门的 ZIP 修复工具就能解开。不过我更推荐的做法是先用unzip -l查看压缩包内的文件列表确认文件是否完整然后再尝试解压。# 检查 ZIP 文件完整性并解压 unzip -t NJU-2024-计算机网络课程实验.zip # 如果输出显示 No errors detected in compressed data说明压缩包完整 # 如果提示 bad CRC 或 unexpected end of file说明文件已损坏需要重新下载 unzip NJU-2024-计算机网络课程实验.zip这段操作的逻辑是先用测试模式检查压缩包的完整性再实际解压。如果遇到“missing zip entry”这类错误说明压缩包内部索引已经损坏解压软件无法还原完整文件结构。这时候不要浪费时间修复直接重新下载原始压缩包通常是最快的办法。我见过有人花了两个小时修复一个损坏的 ZIP最后发现是下载过程中网络中断导致文件截断重新下载一次就解决了。5.2 看不到任何转发流量Mininet 启动失败与接口没起来跑 lab_1 时最典型的问题是start_mininet.py 执行成功后用 pingall 测试主机之间能通但 myhub.py 启动后抓包工具看不到任何流量。这个现象的原因通常是数据包根本没经过 hub或者 hub 程序没有正确绑定虚拟网卡。Mininet 的架构是用户态进程通过虚拟网卡收发数据包如果你的 hub 程序监听的是物理网卡那它当然收不到虚拟网络里的数据包。解决方法是查看 start_mininet.py 中主机和 hub 的拓扑连接方式。标准配置是 hub 连接在交换机位置主机通过虚拟网线连到 hub然后用 tcpdump 在 hub 侧抓包。如果你的 hub 程序是用 socket 原始套接字收发帧要确认绑定的网卡名是否和 Mininet 创建的一致常见是 s1-eth1、s1-eth2 这种命名。另外Mininet 的 controller 默认会启 OpenFlow 流程如果你的 hub 端口没有显式关闭 OpenFlow数据包可能会被 OpenFlow 处理掉而不会到达你的用户态程序。5.3 checksum 校验失败字节序错误和计算范围问题lab_3 到 lab_5 的路由器实验都需要自己计算 IP 报文头部的校验和。常见报错是测试脚本提示收到的数据包 checksum 不对然后丢弃数据包。这个问题背后有两种典型原因。第一种是字节序错误IP 头中的校验和字段是网络字节序大端如果你在计算时用了主机字节序小端计算结果必然错误。第二种是计算范围不对IP 校验和是对整个 IP 头部包括选项字段做二进制反码求和如果你漏掉了某些字段或者多算了负载部分结果也会不一致。def calculate_checksum(header_data): # 标准 IP 校验和计算按 16 位一组做反码求和 if len(header_data) % 2 1: header_data b\x00 # 奇数长度时补零 checksum 0 for i in range(0, len(header_data), 2): word int.from_bytes(header_data[i:i2], byteorderbig) checksum word if checksum 0xffff: checksum (checksum 0xffff) 1 # 回卷 return (~checksum) 0xffff这段代码的逻辑是按 16 位为一组累加遇到进位回卷到最后最后取反得到校验和。需要注意的一个细节是计算时要先把校验和字段置零接收方计算校验和时会把校验和字段也算进去如果等于 0xffff 说明数据正确这是验证实现是否正确的标准做法。5.4 测试脚本跑全量用例时卡死重传超时参数设置不合理lab_6 的可靠传输实验里最让人崩溃的情况是测试脚本跑了十几秒后突然卡住既不报错也不继续。这个现象的原因通常是超时重传参数设置过大。当网络丢包率较高时blaster 发送窗口内的数据包有多个丢失如果 timeout 设置成几秒sender 会长时间等待一个永远不会到达的确认包整个发送过程就停滞了。解决这个问题没有万能参数公式我的经验是让 timeout 和网络的 RTT 匹配。具体做法是在 middlebox 参数文件中把延迟设置为一个已知值比如 50ms然后在 blaster 中把 timeout 设置为这个值的十倍500ms这样既不会频繁重传也不会长时间等待。如果你要模拟真实网络环境可以用 ping 命令测得实际 RTT然后在此基础上增加一定的冗余作为超时时间。5.5 防火墙规则误杀 HTTP 服务匹配顺序和默认策略搞反了lab_7 的防火墙实验涉及 firewall.py、firewall_rules.txt 和一个静态 Web 服务器。最容易踩的坑是防火墙规则顺序导致的错误判断。防火墙处理规则时通常采用“先匹配先执行”的顺序如果你的规则文件里先写了一条拒绝所有流量的规则再写一条允许 HTTP 流量的规则那么即使 HTTP 流量符合允许规则它也会在第一条规则处被拦截。# firewall_rules.txt 的正确书写顺序 # 先写具体的允许规则再写全局的拒绝规则 ALLOW tcp 80 ALLOW tcp 443 DENY tcp all DENY all这种顺序设计的逻辑是像 ACL 那样把具体例外放在前面把通用拒绝放在最后作为兜底策略。如果你反过来写后果就是 Web 服务器完全无法访问因为所有连接都被默认策略拒绝了。实战中还有一个常见误解以为防火墙规则少是不是就安全了。实验包里 www 目录下放着 Web 页面start_webserver.sh 负责启动服务firewall.py 负责过滤流量。我调试时习惯先不加载防火墙规则确认 Web 服务能正常访问后再逐步加入过滤规则这样定位问题就会容易很多。6. 复现实验后的验证方法手动抓包、自动化脚本与性能调参6.1 用 Mininet 手动验证不依赖自带测试实验包自带的测试脚本能自动判断对错但它们是黑匣子——测试失败时你不知道具体是哪个环节出了问题。我的习惯是在跑测试脚本之前先用手动方式验证一遍基础功能。具体操作是启动 Mininet 拓扑后用 tcpdump 在关键节点抓包用 ping 命令测试连通性然后观察数据包的流动路径是否符合预期。# 在 Mininet 中创建拓扑并验证转发功能 sudo mn --custom start_mininet.py --topo mytopo mininet h1 ping h3 mininet xterm h1 h3 # 在 h1 的 xterm 中执行 tcpdump -i h1-eth0 -v # 在 h3 的 xterm 中执行 tcpdump -i h3-eth0 -v这段操作的逻辑是先用自定义拓扑启动 Mininet再用 ping 测试连通性最后打开两台主机的终端并抓包观察。当 h1 ping h3 时如果 h1 发出了 ARP 请求但 h3 没有收到问题在链路层如果 h3 收到了数据包但回包丢失问题在路由器或交换机。手动验证的好处是你能精确控制每个变量的变化不会因为测试脚本的复杂逻辑而分心。6.2 把参数调到“能跑”之外可靠传输的窗口和超时对 lab_6 的可靠传输实验来说“能跑通”只是最低标准我更建议你做一轮参数扫描测试。做法是固定丢包率改变窗口大小记录不同的吞吐量和重传次数画出一条曲线。这个曲线能直观地展示为什么 TCP 需要拥塞控制——窗口太小时信道利用率不足窗口太大时网络会因拥塞而崩溃。# 参数扫描示例固定丢包率 10%改变窗口大小 for window in 1 2 4 8 16 32 64; do echo $window 10000 blaster_params.txt ./start_mininet.py python3 evaluate.py results.csv done这段脚本的逻辑是循环修改窗口参数并运行实验把结果追加到 CSV 文件中。评估脚本 evaluate.py 是自己写的我会记录整个实验的持续时间和成功接收的包数然后计算出有效吞吐量。你会发现当窗口大小从 8 增加到 16 时吞吐量可能有显著提升但从 16 增加到 32 时收益变小甚至下降——这就是网络瓶颈的临界点。6.3 一个直到现在还在用的习惯跑完整个实验包之后我养成了一个习惯每拿到一个新的网络实验项目第一件事就是看它的 README 和参数文件第二件事是跑一次默认配置的测试第三件事是手动改一个参数看看结果变化。这套方法在后续做生产环境网络调试时也一直在用很多定位问题的思路都是从 lab_6 和 lab_7 的排查过程中提炼出来的。回看这套实验包你会发现它最大的价值不是那七个实验本身的答案而是它模拟了真实网络设备的行为方式hub 的广播、交换机的自学习、路由器的转发查表、可靠传输的确认重传、防火墙的规则匹配。这些机制看起来简单但真正用代码实现一遍之后你才会知道哪些细节是会翻车的——比如 IP 校验和的字节序、交换机的 MAC 表淘汰时机、可靠传输的超时阈值。从那以后我每次处理网络相关的问题都强制自己先想清楚数据包从源到目的的完整路径再动手改配置。希望这套实验的复现经验和避坑记录能帮到你。本文还有配套的精品资源点击获取