简介:华北电力大学计算机网络综合实验报告,聚焦网络设备认知与基本配置、互联网综合设计与协议分析两大环节,适合正在学习计网原理或准备课程设计的学生参考。报告基于实际实验环境,梳理了VLAN划分与跨交换机VLAN间通信、单臂路由及三层交换、OSPF多区域配置、静态/动态NAT与NAPT、ACL安全过滤,以及TCP连接抓包与协议分析等内容,并给出了网络拓扑设计与部分关键配置代码。资源为1个doc文档,压缩包总大小21.91MB,文件集中,便于直接阅读和对照练习。目前已有154人学习,可用于理解实验任务书要求、设计思路、开发中遇到的问题及解决方法的完整呈现。对希望系统掌握交换机路由器配置、提高网络排错与实战能力的学习者,这份报告能提供结构化的实验参考和可复现的配置样例,帮助更快上手同类综合实验。
1. 计算机网络实验报告:先想清楚代码和报告谁服务谁
写华北电力大学计算机网络实验报告,最常见的卡点不是“不会写”,而是“没东西写”。Socket调试了大半天,报告里用三段话带过;Wireshark抓了一堆报文,却不知道哪张截图能证明你完成了实验——这种状态交上去,老师一眼就能看出是赶工还是真做。这份实验报告要解决的问题很具体:用一份结构完整的报告加一套能自解释的主要代码,把验证性实验(协议抓包、报文分析)和设计性实验(Socket通信、CRC校验)的得分点全部拿到。适合正被实验报告逼着的在校生、复习408想动手验证协议栈的人,以及刚入行需要补计网底子的从业者。我建议先定报告骨架,再决定代码写多深,顺序反了容易白干。
2. 报告骨架怎么搭:先按实验模板定章节,再决定代码写多深
华电的计算机网络实验通常分两类:一类是验证性实验,在Wireshark里抓协议报文,对照教材分析首部字段;或者在 Cisco Packet Tracer 里配静态路由、看路由表。另一类是设计性实验,用 Socket 写 TCP/UDP 通信程序,或者实现 CRC 校验、滑动窗口。不管是哪一类,报告的章节顺序基本都围着“实验目的、实验环境、实验原理、实验内容与步骤、实验结果与分析、实验总结”这六段转。这不是八股,而是评分点注定了的:目的看的是你为什么做这个实验,原理看的是你对协议栈的理解,结果与分析看的是你有没有把数据讲清楚的能力。所以第一步不是打开 Word,而是把实验指导书里的评分标准读一遍。常见做法是报告占 60%、代码跑通占 30%、答辩问答占 10%,有的老师不收代码只收 PDF,但答辩一定会问代码。这意味着代码必须能跑、能解释、能和报告里的描述完全对上。
# 华北电力大学计算机网络实验报告 - 学院:控制与计算机工程学院 - 专业:计算机科学与技术 / 软件工程 / 网络安全 - 姓名:___ 学号:___ 实验日期:___ ## 一、实验目的 1. 掌握 TCP 三次握手与四次挥手的过程,能用抓包数据复述状态迁移; 2. 掌握 Socket 编程中服务端 bind/listen/accept 与客户端 connect 的调用关系; 3. 掌握 CRC 校验的原理,并用代码验证给定数据的校验值。 ## 二、实验环境 - 操作系统:Windows 10 / Ubuntu 22.04 - 运行环境:Python 3.10(仅标准库 socket、struct、time) - 抓包工具:Wireshark 4.0(需安装 Npcap) ## 三、实验原理 (写协议栈:TCP 报文首部格式、三次握手的 Seq/Ack 变化;CRC 生成多项式与模2除法) ## 四、实验内容与步骤 (先文字描述步骤,再贴核心代码片段,完整代码见附录 src/ 目录) ## 五、实验结果与分析 (终端输出截图 + Wireshark 报文截图 + 逐条分析) ## 六、实验总结 (写一个真实遇到并解决的问题,例如端口冲突、抓包接口选错)这份模板的价值在于它把“分析”和“总结”的位置留得很大。大部分同学只写到“步骤+截图”,实验结果与分析写成“程序运行成功,结果正确”——这种话等于没写。老师想看的是:截图里 SYN 包的序号是多少,ACK 包的 Ack 值为什么是 Seq+1;CRC 算出来是 0x4B37,和标准 CRC-16/MODBUS 的公开校验值一致,说明实现正确。报告里能写出这种句子,得分点就稳稳拿住。反过来,我自己写报告的习惯是先写结果分析,再回头补原理:对着真实报文写原理,语句自然和教材原文不一样,查重也更好看,这是计算机网络实验报告真正见功力的地方。
如果你的课程既有抓包实验又有编程实验,注意验证性实验的截图不要贪多。常见误区是把 Wireshark 里几十条包全截进去,老师看不过来。要点是每个关键状态一张图:三次握手来一张、数据传输来一张、四次挥手来一张,每张图上用红框标出关键字段,下面配两到三行分析文字。设计性实验正好反过来,代码不能贴整段,贴关键行并配解释,完整代码放到附录或单独建一个 src 目录打包提交。这样做的理由是答辩时老师可能现场翻你的源文件,如果报告正文和源文件对不上——比如正文说用了多线程,代码里根本没有——当场就会扣分。
2.1 一份能过查重和答辩的报告,章节顺序藏在实验指导书里
实验目的和实验环境允许通用表达,但实验原理和实验总结要换自己的话。可以参考谢希仁《计算机网络》或者《计算机网络:自顶向下方法》的表述,但不要整段复制。我常用的写法是:读某一节后合上书,用“我理解的 TCP 可靠传输是……”开头写一段真实的理解文字。这种段落在任何查重系统里的重复率都会很低,因为它确实是你自己组织出来的句子,计算机网络基础课上学过的协议栈概念,在这时候正好能用上。另外一个适用细节是:和“头歌”那种在线实训平台不一样,实验室验收看的是代码能不能在本地跑起来,而不是答案字符串匹配不匹配,所以不要把在线实训的答案直接抄进报告。
答辩准备的核心,是给每个实验准备三个问题:为什么要做这个实验?这个协议解决什么问题?参数换一个会怎样?比如“为什么端口大于 1024”就值得想清楚:小于 1024 的端口在 Linux 下需要 root 权限,Windows 下也容易被系统服务占用。这类问题写进报告的原理部分,答辩时就是现成的回答。我见过太多同学背了一堆教材定义,被问到“bind 失败是为什么”直接卡壳,就是因为写报告时只记录结果,没记录决策过程。
2.2 用 Markdown 管理实验文档:代码、截图、报告三处同源
我一般用 Typora 或 VSCode 写 Markdown,然后导出 PDF 交作业。原因很现实:Word 排版容易崩,公式和代码块来回跳格式,而 Markdown 把内容与样式分开,导出的 PDF 干净。截图统一放 images 目录,代码放 src 目录,文件路径用相对路径。目录结构可以按下面这样搭:
network-lab/ ├── report.md # 实验报告正文 ├── report.pdf # 导出后交作业的版本 ├── images/ # 截图统一放这里 │ ├── 01-tcp-handshake.png │ ├── 02-tcp-data.png │ └── 03-udp-packet.png └── src/ ├── tcp_server.py ├── tcp_client.py ├── udp_send.py ├── udp_recv.py ├── crc16.py └── README.md # 每个文件的跑法说明这个目录结构本身也是代码规范的一部分。截图命名用“序号-功能”,不要用“微信图片_20240315”这种默认文件名,老师下载下来一看就知道你没整理过。README.md 里写清每个脚本怎么跑,比如“先终端运行 tcp_server.py,再开一个新终端运行 tcp_client.py”,既是给自己留的后悔药,也是答辩时快速恢复环境的操作手册。两三个月后再回看这份实验报告,如果没有 README,很可能连哪个文件对应哪个实验都要想半天。
2.3 报告里贴多少代码:正文贴关键行,完整代码放附录
写报告最忌讳把代码整段粘进正文。一个 TCP 回射程序一百行,全部贴进“实验内容与步骤”,老师翻三页才能看到结论,等于你在替老师增加工作量。我常用的界限是:正文只贴能说明“流程”的片段,比如 bind/listen/accept 这几行的调用顺序;需要完整逻辑的地方,用“完整代码见 src/tcp_server.py”一句话带过,并在提交目录里保留源文件。代码片段要带注释,注释里写“为什么”,不要写“是什么”。例如这行注释:
# SO_REUSEADDR:允许服务端重启时快速复用端口,避免 TIME_WAIT 导致 bind 失败比“设置 socket 选项”有用得多。这个习惯放到面试和工程里都加分,因为大部分面试官看的不是你背了多少 API,而是你写代码时有没有在脑子里过一遍边界条件。
3. 主要代码写什么:Socket、CRC、UDP 三个代码块直接抄进报告
设计性实验的核心代码要满足三个条件:短、能跑、能用一句话讲清原理。短是为了报告版面好看,能跑是为了答辩现场不翻车,能讲清原理是为了老师问“为什么要这么写”时不冷场。下面三个代码块是我在计网实验里最常用的方案,正好覆盖传输层编程、差错检测、报文收发三个方向。
3.1 TCP回射服务端/客户端:最小可运行示例代码
TCP 回射实验是出现频率最高的题型:客户端发一串字符,服务端原样返回。写进报告里的代码不要用任何第三方框架,用纯标准库 socket,老师一眼能看懂,换机器也能跑。
# -*- coding: utf-8 -*- """TCP 回射服务端:接收客户端数据并原样返回""" import socket HOST = '127.0.0.1' # 只监听本机回环地址 PORT = 8080 # 端口号:0-65535,大于1024避免权限问题 srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) srv.bind((HOST, PORT)) srv.listen(5) # 最多允许5个未完成握手的连接排队 print(f"[*] 服务端启动,等待连接: {HOST}:{PORT}") while True: conn, addr = srv.accept() print(f"[+] 客户端接入: {addr}") while True: data = conn.recv(1024) if not data: break print(f"[←] {addr}: {data.decode('utf-8')}") conn.sendall(data) # 原样回射 conn.close()# -*- coding: utf-8 -*- """TCP 客户端:连接服务端,发送消息并接收回射""" import socket HOST = '127.0.0.1' PORT = 8080 cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM) cli.connect((HOST, PORT)) cli.sendall(b'hello network lab') reply = cli.recv(1024) print(f"[←] 收到回射: {reply.decode('utf-8')}") # 逐行发送,方便观察TCP的字节流边界 for msg in ['A', 'BB', 'CCC']: cli.sendall(msg.encode('utf-8')) resp = cli.recv(1024) print(f"[→] {msg} -> [←] {resp.decode('utf-8')}") cli.close()这段代码的逻辑要能自己讲清楚:服务端socket.socket(AF_INET, SOCK_STREAM)创建 IPv4 TCP 套接字;bind把套接字绑到本机回环地址和端口 8080 上,客户端connect时必须连同一个端口;listen(5)表示内核里为这个监听套接字排队的最大未完成连接数,5 不需要很大;accept阻塞等待客户端接入,返回一个新的连接套接字conn,接下来收发数据都走conn而不是srv——srv只管听,conn才管说,这是 TCP 编程里最容易搞混的点。
参数说明:HOST 默认 127.0.0.1 表示只在本机跑,如果要两台机器联调,服务端 HOST 改成 0.0.0.0 表示监听所有网卡,客户端 HOST 改成服务端机器的局域网 IP。PORT 在 1024 到 65535 之间选一个没被占用的,8080 被占用就试 8081、9090。客户端后面三行循环发 A、BB、CCC,这是故意用来观察 TCP 字节流边界的:TCP 没有消息边界,一次sendall不一定对应一次recv。报告里写出“A、BB、CCC 三次发送,服务端可能一次 recv 就收到 ABBCCC”,老师就知道你真正跑过、踩过这个坑。
注意:
recv(1024)的意思是“最多读 1024 字节”,不保证一次就拿到一条完整消息。服务端循环 recv 直到返回空字节串,才表示对端关闭了连接。
3.2 CRC校验:逐位法代码可读性最好,先跑测试向量再贴报告
CRC 校验是差错检测专题的经典实验。逐位法实现直观,每一步都在模拟模 2 除法,最适合写进报告讲原理。
# -*- coding: utf-8 -*- """CRC-16/MODBUS 逐位法实现:适合报告讲解原理""" def crc16_modbus(data: bytes, poly: int = 0x8005, init: int = 0xFFFF) -> int: crc = init for byte in data: crc ^= byte << 8 for _ in range(8): # 逐位处理,一个字节8位 if crc & 0x8000: # 最高位为1,执行模2除法 crc = ((crc << 1) ^ poly) & 0xFFFF else: crc = (crc << 1) & 0xFFFF return crc if __name__ == '__main__': test = b'123456789' print(hex(crc16_modbus(test))) # 预期输出 0x4b37CRC 的运算本质是模 2 除法:把数据当作一个很长的二进制数,除以生成多项式,余数就是校验值。逐位法逐字节处理,每个字节 8 位,手工模拟除法的每一步。crc初始值 0xFFFF 是 CRC-16/MODBUS 的规定;poly=0x8005是生成多项式的十六进制表示,对应二进制 1000000000000101,即 x16+x15+x2+1。位运算里crc & 0x8000判断当前最高位是否为 1,是则左移一位后与多项式异或,否则只左移;& 0xFFFF保证结果不超过 16 位。新手最容易翻车的地方是运算符优先级——(crc << 1) ^ poly一定要加括号,否则crc << (1 ^ poly)结果全错。
注意:公开测试向量为 b"123456789",对应 CRC-16/MODBUS 的校验值是 0x4B37。如果输出不一致,先检查多项式、初始值和括号,不要带着错误结果写进报告。
为什么要先跑测试向量再贴报告?因为 CRC 的参数组合太多,多项式、初始值、输入是否反转、输出是否反转,任意一个不一样结果就不同。先固定一个公开标准,用标准向量验证实现正确,再往报告里写。顺带提醒:Wireshark 里看到的数据包校验和是 Internet Checksum(反码求和),和 CRC 是两套东西,实验报告里不要混用,这是很多同学被老师当场纠错的高频点。
3.3 UDP发送/接收:无连接的特性用两段代码对比着看
UDP 实验通常比 TCP 简单,但它能验证“无连接”这个核心概念。发送端和接收端要分两个文件写,不要放在同一个脚本里。
# udp_send.py import socket s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.sendto(b'hello udp', ('127.0.0.1', 9090))# udp_recv.py import socket s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.bind(('127.0.0.1', 9090)) data, addr = s.recvfrom(1024) print(data, addr)UDP 的 socket 类型是SOCK_DGRAM,对应数据报服务。发送端sendto直接发包,接收端bind后recvfrom返回数据和发送方地址,整个过程没有 listen、accept、connect,这就是“无连接”的表现——不需要建立连接就能发包,代价是不可靠、不保证有序、不保证不重复。实验报告里如何呈现:先抓 TCP 的包,再抓 UDP 的包,对比两种协议首部和握手过程。UDP 首部只有 8 字节:源端口 2、目的端口 2、长度 2、校验和 2。抓包时发一条 5 字节的消息,看 Wireshark 里 UDP Length 字段显示 13,就能在报告里写出“数据长度 5,UDP 首部 8,长度字段=8+5=13,与抓包结果一致”这种可验证的结论。相比之下 TCP 首部固定 20 字节,有序列号、确认号、窗口、标志位,两相对比,传输层两种协议的设计取舍就讲清楚了。
如果只要求做 UDP 实验,建议顺手给接收端加上超时设置:s.settimeout(3),然后故意停掉发送端,看接收端抛socket.timeout。这正好说明 UDP 没有保活机制,应用层必须自己处理超时。写进“实验总结”里,比一句“我学会了 UDP 编程”有说服力得多。
4. 验证实验结果的三个手段:抓包、终端输出、故障注入
写报告不是把代码跑一遍就完,而是要留下证据链:终端输出证明程序按预期工作,Wireshark 截图证明网络行为符合协议,故障注入证明你知道边界在哪。这三样凑齐,“实验结果与分析”章节就是满的。下面按我的习惯把三个手段拆开说,每一步都是可以直接复现的操作。
4.1 用Wireshark抓TCP三次握手:选对回环接口,过滤出四条关键报文
操作步骤:先启动 Wireshark,在接口列表里选Loopback: lo(Windows 下显示为 Loopback 或 Npcap Loopback Adapter)。很多人第一次抓包一条都看不到,就是因为选成了 WLAN 或以太网——本机两个进程通信的数据包根本不经过物理网卡,只在回环接口里走。选完接口再运行 server 和 client,抓包结果会很干净。
抓完包后最有用的是下面这条过滤表达式:
tcp.port == 8080 && tcp.flags.syn == 1这个过滤条件显示所有经过 8080 端口且 SYN 标志位为 1 的包。实际抓包结果一般是:客户端→服务端 SYN(Seq=0);服务端→客户端 SYN+ACK(Seq=0,Ack=1);客户端→服务端 ACK(Seq=1,Ack=1)。第三次握手的 Ack 值等于第一次握手的 Seq+1,这是报告里值得标红的一句分析。顺手再抓四次挥手:关闭客户端连接时,客户端→服务端 FIN+ACK、服务端→ACK、服务端→FIN+ACK、客户端→ACK,可以用tcp.flags.fin == 1过滤。把这五张截图做完标注放进报告,验证性实验的得分点基本就拿到了。
为什么握手要三次而不是两次?因为 TCP 要确认双方收发能力都正常:第一次 SYN 只有客户端证明自己能发;第二次 SYN+ACK 让客户端确认服务端能收也能发,但服务端此时还不知道客户端能不能收,所以还需要第三次 ACK。用抓包的包号对应讲解这个推导,比干背教材好记。期末复习计算机网络时,这又是 408 的高频考点,亲手抓过包之后记忆会深很多。
4.2 故障注入:故意写错端口和IP,让报告里有一段真实的异常排查
故障注入不是造假,是用可控的方式构造失败场景,验证你对协议的理解。我在实验里常用的有三个做法。第一,把客户端端口改成一个没有服务监听的端口(比如 8081),运行会抛ConnectionRefusedError: [WinError 10061],把报错截图放进报告,分析“服务端没有监听 8081,客户端发 SYN 后对端 TCP 协议栈回了 RST,所以立即拒绝”。第二,把客户端 HOST 改成不可达地址,会等到超时,抛TimeoutError,分析“目标不可达时 SYN 没人回应,客户端等待重传超时”。第三,把发送数据改成超过缓冲区的大包,观察报错或 Wireshark 里的分段现象。这三个都是纯本地的实验设计,不需要任何外部网络权限。
报告里的写法是固定的:现象(贴截图)→猜测原因(用自己的话写)→验证(改配置复测)→结论。例如“把端口改回 8080 后连接成功,证明问题出在端口不匹配而不是代码逻辑”。老师看到这种段落,通常不会再怀疑你是不是抄的,因为这明显是真实排查过才能写出来的内容。
4.3 终端日志加时间戳:让报告数据能和Wireshark逐条对上
很多同学的终端输出只有“收到:hello”,没有时间、没有序号,报告分析无从下手。我一般会给服务端打印加上时间戳和序号,代价只有几行代码:
import time seq = 0 while True: data = conn.recv(1024) if not data: break seq += 1 print(f"[{time.strftime('%H:%M:%S')}] #{seq} {addr}: {data}")逻辑说明:time.strftime('%H:%M:%S')输出时分秒,和 Wireshark 主界面的 Time 列对照,能确认终端第 3 条消息正好对应抓包里第 12 个数据包。序号则让报告里能写“连续发送三条消息,服务端按序收到”,也方便观察乱序。这是很基本的代码规范,但十个提交的报告里九个没这个习惯,做出来就是差异点。顺带一提,如果程序卡住不动,看时间戳能一眼看出是 recv 在阻塞还是程序进了死循环,省去一堆调试时间。
5. 计算机网络实验避坑:五个让实验翻车的细节
实验报告翻车的现场一般不在写报告时,而在跑代码和答辩的瞬间。下面五条是我见过最多的踩坑记录,按现象、原因、解决三步写,每条都能帮你省下至少半小时到一天的排查时间。
5.1 在实验室机器上跑代码:先解决“找不到msvcp140.dll”这类环境问题
现象:自己的笔记本上跑得好好的,到实验室机器上打开 Python 脚本,直接弹窗“由于找不到msvcp140.dll无法继续执行代码”,或者 import 第三方库报 ModuleNotFoundError。
原因:msvcp140.dll 是 Visual C++ 2015-2022 运行库的一部分,很多精简版 Windows 或没装过 Visual Studio 的机器上缺失;第三方库报错则是因为实验室的 Python 环境是精简版,没装你本地用 pip 装过的那些包。
解决:实验代码只依赖 Python 标准库(socket、struct、time、threading),全程不 import 任何第三方库。这样换机器只需要有 Python 本体就能跑。替代方案是用 zip 打包一个嵌入式 Python 环境带走,但学校机房可能限制 U 盘和联网,所以最稳妥的还是实验环境栏里写明 Python 版本和零第三方依赖。如果老师允许联网,可以在实验室机器上执行python -m pip install,但我不推荐在报告里引入非标准库依赖,答辩现场环境不可控,这是血泪经验换来的。
5.2 服务端只能收一条消息:recv循环没有套在连接里
现象:客户端发第一条消息,服务端正常回射;再发第二条,服务端没反应,直到客户端断开重连才能继续。
原因:服务端的 recv 只调用了一次就退出,或者内层循环的退出条件写错,把整个连接处理逻辑套死。TCP 是流式的,一条连接上可以收发任意多条消息,必须在 accept 得到的 conn 上循环 recv。
解决:参考前面 3.1 的代码,内层while True保留,recv的退出条件设成if not data: break,也就是对端关闭连接时 recv 返回空字节串。容易写漏的同学,把conn.close()放在内层循环之后。写进报告的注释可以是:
# 循环接收直到客户端关闭,否则一条连接只能处理一条消息5.3 CRC结果和标准值对不上:先查多项式、初始值和括号
现象:同一份数据,自己算的 CRC 和网上的 CRC 计算工具结果不一样,和 Wireshark 里看到的值也不一样,怀疑代码有 bug,但逐行看又看不出问题。
原因:CRC 家族参数太多,多项式、初始值、输入反转、输出反转、结果异或值,任意一项不同结果就不同。另外位运算优先级写错也是常见原因,(crc << 1) ^ poly和crc << (1 ^ poly)在 Python 里的执行结果完全是两回事,前者才是想要的模 2 除法步进。
解决:先固定标准,比如用 CRC-16/MODBUS(poly=0x8005、init=0xFFFF),拿公开测试向量 b"123456789" 跑,正确输出是 0x4B37。对得上再贴报告;对不上就按“多项式→初始值→括号”的顺序逐项排查。再强调一次:不要把 UDP 校验和(Internet Checksum,反码求和)和 CRC 混为一谈,抓包软件显示的首部校验和是前者,不是后者,报告里不能互换。
5.4 Wireshark一条包都抓不到:八成是接口选错了,不是代码问题
现象:两个终端都能正常收发,程序输出正确,但打开 Wireshark 抓包,一条数据都没有。
原因:没选回环接口。本机两个进程通信的包只经过 Loopback,不经过物理网卡;另外 Wireshark 没有安装 Npcap 驱动时,回环接口也捕不到数据。很多人直接在 Wireshark 主界面双击“以太网”就开始抓,当然什么都看不到。
解决:抓包前先看接口列表,选名为 Loopback 或 lo 的接口,Windows 下可能是 Npcap Loopback Adapter。过滤表达式用tcp.port == 8080配合,排除 ARP、DNS 等噪声。如果接口列表里压根没有回环接口,说明 Npcap 没装好,重新安装 Wireshark 时勾选 “Install Npcap”,装完重启再试。这些步骤写进报告“实验环境”里,老师会觉得你很严谨。
5.5 答辩被问倒:报告里没留“为什么”,只会念结论
现象:报告写的“实验成功,结果正确”,答辩时老师指着 bind 问“为什么必须 bind”,你只能回答“照着书上写的”,现场尬住。
原因:写报告时只记录结果,没记录决策过程。老师的提问套路全是“为什么”:为什么用 TCP 不用 UDP?为什么端口大于 1024?为什么 listen 参数写 5 不写 100?任何一个没想过的问题都会卡壳。
解决:给原理部分每一段都补一个“为什么”句式。比如“bind 将套接字绑定到指定 IP 和端口,不 bind 时系统会自动分配临时端口,客户端就无法预先知道连接哪个端口,因此服务端必须 bind”。这类句子就是前面说的“用自己理解的话写原理”,查重率低,答辩时还能直接背出来。这个习惯对 408 考生也有用:计算机网络题复习题库里的高频问法,全是这种“为什么/如果换一个参数”的变形题,平时在实验报告里练过,考试就不会慌。
6. 这份实验报告的三层进阶:代码、协议、408复习一起拿下
实验做完报告交掉,其实还有三个顺手可做的进阶动作,花不了多少时间,但能把这份作业的价值榨干。第一个,把 TCP 回射程序改成多客户端并发。只需要在 accept 之后把 conn 丢给一个线程处理,核心代码就一行:threading.Thread(target=handle_conn, args=(conn, addr)).start()。跑通后对比单线程版,你会发现单线程版服务端被第一个客户端占死,第二个客户端连进来一直没人应答——这个对比写进实验总结,比任何套话都有说服力。
第二个,CRC 从逐位法升级成查表法。查表法的思路是把一个字节 256 种取值对应的 CRC 结果预先算好,运行时每字节只查一次表,比逐位法快约 8 倍。核心逻辑是先用循环生成 256 项的 crc_table,然后对每个字节执行crc = (crc >> 8) ^ table[(crc ^ byte) & 0xFF]。如果能顺手把逐位法和查表法跑同一段 1MB 随机数据对比耗时,时间差至少一个数量级,这个数据本身就是很好的实验结果。工程上无人不用查表法,面试聊到 CRC 时能说出“逐位法适合教学、查表法适合生产”,印象分会好很多。
第三个,把这份实验和 408 复习资料对上号。谢希仁《计算机网络》、《计算机网络:自顶向下方法》、王道考研讲义,这三套资料讲 TCP 三次握手和可靠传输的部分,你都能用这次的抓包截图和 Socket 代码去反推。湖科大教书匠的系列视频里有动画演示的协议流程,配合你自己抓的包里真实的 SYN、ACK 序号看,记忆会非常牢。历年 408 真题里的代码题很少直接考 Socket,但 TCP 状态迁移、UDP 首部结构、CRC 差错检测这些概念,亲手实现过一遍之后,做题速度和准确率都会不一样。
我自己的教训是:有一年我把 server 和 client 写进同一个文件交上去,实验虽然跑通了,但答辩老师问“服务端和客户端分文件是不是更清晰”,当时只能承认图省事。从那以后再小的实验,我也坚持一个实验一个目录,Server.py、Client.py、CRC.py 各司其职,README 写清跑法。这个习惯后来帮过我好几次——换机器、重装系统、半年后回看,都能十分钟恢复现场。实验报告这东西,写的时候越把它当工程做,交的时候就越踏实。希望帮到你。
本文还有配套的精品资源,点击获取