
简介南京大学2024年计算机网络课程实验合集涵盖lab_1至lab_7共七个递进式实验涉及集线器/交换机转发、路由器配置、防火墙设置、可靠传输模拟等主题适合学习网络原理的学生、自学者或需要参考实验设计的教师。压缩包共38个文件主体是29个Python脚本另含6个文本配置说明、1份README指南、1个Shell启动脚本与1份pcap抓包数据整体大小约39KB轻量易查阅。目前已有160人学习。借助实验源码、测试脚本和抓包文件可以还原每个实验的操作流程与验证方法比如查看二层交换逻辑、路由表与防火墙规则设计以及模拟网络通信中的丢包和重传。如果希望快速了解南大课程实验结构或用Mininet搭建类似环境进一步练习这套资料能提供直接的参考和动手基础。1. 这个压缩包是南大计网课程的“实弹训练”先想清楚它值不值得花一个学期期末前两周课程群里常见“求一个做完的NJU-2024-计算机网络课程实验.zip”——这是南京大学2024年计网课程实验的整套打包实验指导、代码框架、评测脚本都在里面。它练的不是背出TCP三次握手而是把socket通信、抓包分析、可靠传输、路由模拟从头到尾跑一遍。很多人的真实状态是解压十分钟跑通第一个demo两小时。读这篇的人大多带着三个问题这包值不值得逐行啃、按什么顺序做容易拿分、做完后的参数能不能顶到面试里。这篇不讲虚的只讲怎么做、坑在哪。在校生、求职者和想补网络基本功的工程师都能从这套实验里拿到各自要的东西前提是愿意在看不见的协议状态上花时间。2. 解开压缩包先盘家底目录结构、运行环境与最小启动命令2.1 实验包该有的模块从Socket到路由模拟这类计网课程实验包通常装四样东西实验指导书、源码框架、测试脚本、样例包。指导书告诉你评分点源码框架把最麻烦的序列化和拓扑解析写好测试脚本就是你拿分时会被调用的东西样例包里是已经抓好的报文用来对着改代码。四样东西里指导书最容易被忽略但README里往往写清楚了“评测时只看哪些输出”这比你自己琢磨代码管用得多。模块顺序也基本固定先是Socket编程再做HTTP与抓包分析接着是实现可靠数据传输最后做路由协议模拟。难度不是线性涨的Lab1会卡在并发和分包Lab2卡在过滤器写不好Lab3和Lab4是真正让多数人熬夜的地方因为它们考的是协议状态机——GBN的窗口怎么重传、RIP的坏消息怎么传播这些在书上看都懂写进代码就是另外一回事。配套教材的话我一般推荐一个组合实验主视角用《计算机网络自顶向下》对照分层设计和Socket讲解《谢希仁计算机网络》用来补协议细节。如果目标是备考408王道和湖科大教书匠的网课能把“为什么这样设计”讲透但实验里的工程坑课里不会讲得自己踩。拿到包先别急着解压先看README和test目录按多数实验包的通行布局“家底”大体长这样目录常见内容建议优先级LAB1_Socket/client/server 框架、Makefile 或 requirements先跑通LAB2_Packet/抓包指导、样例 pcap 文件阅读为主LAB3_RDT/报文序列化框架、丢包模拟器分配最多时间LAB4_Routing/拓扑文件、转发逻辑框架最后冲刺2.2 先将环境对齐选版本本身就是避坑课程实验最容易被环境吃掉时间。按下面这套省心组合来绝大多数情况不会卡壳Python 选 3.8 到 3.12 之间不要追求最新版框架里如果用了 scapy 这类依赖新版解释器发布后兼容补丁不一定跟上import 直接失败Wireshark 装 4.xWindows 下安装时要勾选安装 NpcapLinux 装好后把当前用户加进 wireshark 组否则打开时接口列表全是灰的路由模拟实验尽量用普通 Linux 虚拟机跑WSL2 日常写代码够用但虚拟网卡行为和真实 Linux 不完全一样实验现象不符合预期时先怀疑环境而不是源码。提交作业多数要求 zip 包用zip -r 学号-姓名.zip 学号-姓名/打包提交前用unzip -l检查文件名和内容再传。这套组合里最值得记的是版本不要乱升计网实验不是生产项目框架通常只在某个 Python 小版本上测过我见过有人用新版本解释器跑实验框架scapy 直接报错两小时全花在解决依赖上这是血泪经验。动手前先自检三条命令环境对不对一眼看清python3 -V wireshark --version gcc --version2.3 最小启动命令从解压到跑通框架自检解压这步有一个高频坑Windows 里打包的 zip文件名是 GBK 编码直接 unzip 会变成乱码源码里出现“锟斤拷”。常见做法是解压时指定编码然后立刻看目录结构和跑自测# 用 -O gbk 按GBK解压避免中文文件名乱码macOS自带unzip不支持该参数用7z或p7zip替代 unzip -O gbk NJU-2024-计算机网络课程实验.zip -d nju_cnlab cd nju_cnlab # 看看包里到底有什么 find . -maxdepth 2 -type d | sort # 先跑框架自带的自测环境对不对这一条就能试出来 python3 -m unittest discover -s LAB1_Socket -v第一条命令里的-O gbk是关键同一个 zip 在 Windows 下正常换到 macOS/Linux 就乱码属于典型的换电脑就翻车。如果解压时直接报invalid zip archive: could not find EOCD说明文件没下完整或者传输被截断先重新下载再用unzip -t测试完整性。find命令不是炫技而是让你在改代码前确认四个目录都在很多同学上来就进 src改到一半发现测试脚本在 test 目录评分读取 log 文件搞错位置就全白做。先跑自测更重要一个能过的单元测试说明依赖装齐了、端口能绑、基础网络栈没被系统策略拦住。如果自测失败记录第一行报错而不是整个终端刷屏的堆栈多半是路径带空格、python 命令指向错误版本或者依赖没装。自测通过后建议立刻git init git add -A git commit——课程实验是反复改 bug 的过程保留一个初始干净版本后面把框架改坏时随时回滚这就是你的后悔药。不需要推送到任何远程库本地仓库就够。3. 从零跑通Socket实验一个可复现的TCP并发服务器与三个参数坑3.1 实验要求拆解客户端/服务器各要交付什么Lab1 一般做的是 echo server 或文件传输客户端连上、发消息、服务器原样返回或落盘。功能本身不难难的是评测脚本怎么调用你。常见的评测方式是启动 server然后并发拉起几十个 client每个 client 发送长度不同的内容再逐字节核对返回值还会在传输过程中直接掐断连接看你的 server 是否崩溃。所以交付的不只是“能聊天的程序”而是四件事能并发接受多个连接、对半分片或粘包的内容也能还原、异常断开不会带走整个进程、日志能指出每个连接从建立到关闭的状态变化。这四点分别对应并发模型、消息边界、异常处理和可观测性也正是计网面试里被反复问的四个点。3.2 TCP并发服务器参考实现Python给一个能直接跑的最小参考。它用定长帧头解决粘包用 read_exact 解决半包线程模型处理并发SO_REUSEADDR 解决实验机重复启动 bind 失败import socket import threading import struct def handle_client(conn, addr): # 帧格式前4字节为大端长度后面是payload def read_exact(n): buf b while len(buf) n: chunk conn.recv(n - len(buf)) if not chunk: raise EOFError(client closed early) buf chunk return buf try: length struct.unpack(!I, read_exact(4))[0] payload read_exact(length) # echo按帧原样返回 conn.sendall(struct.pack(!I, length) payload) except Exception as e: print(f[{addr}] error: {e}, flushTrue) finally: conn.close() def main(): srv socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 这个参数必须放在bind之前否则TIME_WAIT会让第二次启动失败 srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) srv.bind((0.0.0.0, 8080)) srv.listen(128) while True: conn, addr srv.accept() threading.Thread(targethandle_client, args(conn, addr), daemonTrue).start() if __name__ __main__: main()read_exact 是这版的核心。TCP 是字节流recv 返回的字节数不保证等于消息长度所以先定好“前 4 字节无符号大端整数是负载长度”再按长度把内容收满。客户端发的时候也遵循这个帧格式就不会发生粘包拆包混乱。SO_REUSEADDR 要放在 bind 之前才生效这个参数解决的是 TIME_WAIT 状态下端口被占用的问题实验场景里服务器反复重启不加它第一次正常第二次就报 Address already in use。listen(128) 的 128 是 backlog指内核为这个监听 socket 排队的连接数不是并发上限。做并发压测时如果 accept 处理得慢超过 128 的连接会排队被内核丢弃表现为客户端 connect 超时。换成 selectors 或 asyncio 能处理更高并发但课程评分一般不要求手写线程模型最容易向面试官讲清楚每个客户端连接做了哪些事。3.3 三个必调参数recv缓冲区、超时、listen队列第一个常见错误是把 recv 的 n 设成 1。比如data conn.recv(1)加循环去拼包逻辑上没错但每收一个字节都是一次系统调用CPU 马上被打满数据量一大就变成蜗牛。用recv(4096)一次性拿大块再从缓冲区按帧取。第二个是忘记给连接设置超时。客户端建立连接后不发数据线程就永久阻塞多个这样的连接会把线程耗尽。在 handle_client 开头加conn.settimeout(5)超时抛异常后走异常分支关闭连接。第三个是 listen 队列设置得不合适。实验机本地压测128 够用如果要演示并发上限可以调到 1024 并观察ss -tnl里的 Send-Q。记住它和并发上限不是一回事别在报告里写错。这三个参数背后的道理是应用层和传输层的边界问题TCP 保证字节有序不丢失但消息边界、超时策略和并发策略都是应用层责任。面试官顺着这个思路问下去你还会聊到滑动窗口和拥塞控制正好对应后面的可靠传输实验。4. 抓包实验的上手路径Wireshark过滤器与三个隐蔽坑4.1 抓包实验的评分点不是抓到包是过滤器写对抓包实验最翻车的不是抓不到而是抓到一大堆不知道怎么交差。评分老师通常只看三样过滤器表达式写没写对、关键报文有没有标出来、报告里的序号/确认号/时间对不对得上。所以动手抓包前先想明白要验证哪条协议行为——三次握手、HTTP 请求响应还是重传然后只抓这个范围别开全局捕获。课程实验里有一类经典题目利用 Wireshark 观察 TCP 三次握手的序列号变化。你要能指出 SYN 包的 seq、SYN-ACK 包的 seq 和 ack以及双方 seq 的递增规律。这个观察过程比截图本身重要因为很多框架自带日志不打印网络层数据抓包是唯一能证明你“真的发了这些报文”的途径。4.2 必背的过滤器表达式一张表解决大多数课程评分点实验场景显示过滤器说明抓本机实验端口tcp.port 8080只看这个端口的双向流量区分单台主机ip.addr 192.168.1.5 tcp双向都显示看三次握手tcp.flags.syn 1 || tcp.flags.ack 1快速筛握手包找HTTP请求http.request.method GET只显示GET请求找响应状态码http.response.code 200只看成功响应本机回环通信ip.addr 127.0.0.1客户端服务器在同一台机器注意 Wireshark 有两套过滤器捕获过滤器BPF 语法和显示过滤器。课程实验写进报告的是显示过滤器语法像tcp.port 8080。新手容易下意识在显示过滤栏里填port 8080那是 BPF 语法马上报错这是最常见的零分操作。4.3 三个隐蔽坑环回口、无权限、TLS加密第一个坑是本机通信抓不到。客户端和服务器都在同一台机器上流量走的是 loopback 接口Wireshark 默认抓物理网卡所以你看到的是空。解决界面选 Loopback: lo或命令行用-i lo。有的虚拟机里有两张虚拟网卡选错了另外一张也会空。第二个坑是权限。Linux 里普通用户打开 Wireshark接口列表一片灰提示没有权限。不要去sudo wireshark那样抓到的文件归属 root后续报告整理和文件导出都别扭。正确做法是sudo usermod -aG wireshark 你的用户名重新登录后再开。第三个坑是抓了一堆 TLS 密文。现在很多服务默认 HTTPS/QUIC课程实验要求看 HTTP 明文时要么在实验环境里自己起明文 HTTP 服务要么临时关掉协议自动升级。报告中遇到加密报文要写清楚“由于 TLS 加密application data 不可读握手阶段可见”这比硬编造一段 HTTP 请求诚实得多也符合计网实验重过程、轻结果的评分风格。再补一个玄学防火墙有时会拦回环数据包过滤器正确、接口正确还是空时关掉防火墙再试一次大多数情况是这个原因。报告里放截图时记得在图上标注关键字段序号、确认号、窗口用 Wireshark 左下角的 Expert Info 看异常报文写一句“这里出现乱序重传原因是发送端突发量过大”这类观察比堆十张截图得分高。5. 避坑可靠传输与路由模拟里最容易翻车的5个问题5.1 可靠传输实验窗口、丢包与超时重传的置错点可靠传输实验是所有计网实验里最像真实工程的基于 UDP 实现一个可靠协议还要在丢包模拟器下测吞吐。大部分课程框架会给你一个 send/recv 的桩要求实现 seq 编号、ACK、超时重传和窗口。光把功能跑通不难难的是在 2% 丢包率下让它表现正常。设计上有三个参数决定成败窗口大小、超时时间、丢包注入方式。窗口太大重传风暴会把带宽打没窗口太小吞吐上不去。超时时间比 RTT 短会疯狂重传比 RTT 长太多性能白白浪费。丢包注入最好是可配置的不要写死在 random 里否则测试时丢包率不可控报告里的实验数据也没法复现。选 GBN 还是 SR课程要求说了算。GBN 接收方只需要一个窗口、发累积 ACK实现简单但丢包率高时重传量大SR 接收方要维护重排缓冲区实现复杂但在高丢包率下吞吐明显更好。面试常问“为什么丢包率到 5% 时 GBN 几乎不可用”答案就是累积重传放大。5.2 路由模拟毒性逆转、无穷计数与拓扑收敛路由模拟实验里常见的是实现 RIP 距离向量或者按老师要求实现链路状态。距离向量算法有一个著名毛病好消息传得快坏消息传得慢。A-B-C 链路里 C 断掉B 发现不可达广播给 AA 又把自己的旧路由传回给 B形成计数到无穷大。课程老师喜欢在拓扑里埋这个实验点让你观察收敛轮数。排错时先检查三件事是否实现了毒性逆转是否做了水平分割路由更新定时器有没有和转发逻辑混在一起。很多同学把“定时广播路由表”和“收到更新后立即重算”写进同一个循环结果是同一轮里你改我、我改你下一跳不停震荡。常见做法是分成两个事件更新定时器只负责发送当前表收到消息再触发重算。5.3 现象 → 原因 → 解决五条踩坑记录现象UDP 模拟实验里客户端发出去的包经常收不到或乱序。原因接收缓冲区用的是默认大小约 8KB模拟器一旦突发多包内核直接丢包。解决在 socket 上显式设置SO_RCVBUF到 65535 甚至更大把缓冲区配置写进实验报告说明这是测量后的选择。现象GBN 在 1% 丢包率下吞吐降到几乎为 0。原因超时重传时间拍脑袋设成 10ms实际 RTT 大概 30ms发送方还没收到 ACK 就超时于是反复重传。解决先用 ping 等方式估算 RTT 基数把超时设成平均 RTT 的 2 到 3 倍并做指数退避实验数据立刻正常。现象路由模拟里始终存在环路收敛很多轮也不结束。原因距离向量实现里没有毒性逆转对不可达邻居还把旧路由广播出去。解决对下一跳指向本路由器的邻居把对应目的网络的 metric 设为 16 跳RIP 的无穷大同时开启水平分割把这条写进 README 并展示收敛前后表项对比。现象并发压测到几百个连接时 server 卡死或者 Segmentation fault。原因多个线程共享同一个路由表或日志缓冲不加锁导致数据竞争少数情况是每个线程的默认栈不够大。解决每个连接持有一个独立 buffer全局日志统一加锁想更简洁就换成 selectors 单线程多路复用课程报告里还能多一个加分点。现象解压后文件名全是乱码源码文件里出现“锟斤拷”。原因压缩包在 Windows 下用 GBK 编码文件名类 Unix 解压工具默认按 UTF-8 解析。解决解压时用unzip -O gbk已经解压坏的目录用convmv -f GBK -t UTF-8 --notest -r .批量转码之后重新跑测试脚本确认没有文件被漏解压。6. 验收与复盘三分钟确认实验做完还能把它讲成项目经验课程实验的最后一个环节往往被低估验收。按下提交按钮之前用一个三分钟的脚本检查服务器状态、并发能力和抓包结果。下面是一段可直接改的 bash 验收片段适用于跑在本机的 Socket 或抓包实验# 1. 端口在听看LISTEN和进程 ss -tlnp | grep 8080 # 2. 并发连接短时间拉50个连接数established for i in $(seq 1 50); do curl -s http://127.0.0.1:8080/health /dev/null done sleep 2 ss -tn state established ( dport :8080 ) | wc -l # 3. 抓三次握手只抓回环口上的SYN/SYN-ACK/ACK tshark -i lo -c 3 -f tcp port 8080 -Y tcp.flags.syn1 || tcp.flags.ack1第一段检查端口有没有起来第二段验证并发第三段直接看协议层。三条都过说明代码在“能用”之外还有证据任何一条没过按第 5 章的坑去排查。如果机器里没装 tshark直接在 Wireshark 图形界面套同样的过滤器条件也可以效果等价。如果你走的是面试或校招方向这套实验非常适合写进项目经历不要写“熟悉 TCP/IP”写“实现基于 UDP 的可靠传输协议窗口和超时参数可调支持注入 2% 丢包观察吞吐变化”。后者一拿出来就是话题面试官可以直接追问窗口怎么选、重传怎么退避。devops 工程师也一样线上服务大量 TIME_WAIT、负载均衡连接打满这些场景和实验里的参数坑是同一套底层逻辑。最后说一个我自己的习惯。当年做可靠传输实验为了追求大窗口把超时时间写成 10ms结果在平均 RTT 30ms 的模拟器上疯狂重传一晚上没跑出有效数据后来养成习惯改任何参数之前先把当前链路的 RTT 和丢包率测一遍作为基线。计网实验真正值的不是那几个学分是你以后排查问题时的本能——先测量再动手。希望帮到你。本文还有配套的精品资源点击获取