从实验报告到工程手册:TCP/UDP与Wireshark抓包实战指南

发布时间:2026/10/8 9:00:14
从实验报告到工程手册:TCP/UDP与Wireshark抓包实战指南 简介这份资源是广东工业大学计算机学院2015年计算机网络课程的实验报告PDF面向正在修读计算机网络实验、需要参考实验流程与报告写法的本科生尤其适合使用GNS3开展交换机与VLAN实验的同学。压缩包内仅含1个PDF文件大小约1.17MB内容以图文形式记录实验过程与结果便于直接查阅和打印。报告围绕GNS3安装使用与交换机技术展开涵盖网络拓扑搭建、设备基础操作、交换机配置、VLAN划分及VLAN间通信等实验目的并附有同VLAN与跨VLAN连通性测试的截图与说明还记录了通过Wireshark抓取Trunk流量、分析IEEE 802.3帧结构与CDP协议标签的过程。读者可借此了解实验报告的完整结构、测试步骤与结果分析写法对照自己的实验环境查漏补缺。目前已有71人学习适合作为课程实验的参考范例。1. 一份实验报告为什么值得当成工程手册来读很多人看到“广工2015年计算机网络实验报告.pdf”这个文件名第一反应是这不就是一份学生作业吗有什么好看的。但如果你真正带过新人、或者自己从抓包开始学网络就会知道这类实验报告里藏着一套非常完整的“从零把协议跑起来”的路径。它通常覆盖 socket 编程、TCP/UDP 对比、抓包分析、HTTP 请求构造、路由与子网划分这几块恰好是网络工程里最核心的基本功。问题在于报告本身是给老师看的步骤跳跃、环境依赖没写清、参数含义一笔带过直接照着做大概率卡在环境配置和结果对不上这两步。这篇笔记要做的就是把这类实验报告拆成一份能复现、能排错、能迁移到真实工作的操作手册适合刚入行的网络方向新人也适合想补底层协议的开发同学。2. 先搞清楚实验环境抓包工具与 socket 编程的选型逻辑2.1 为什么 2015 年前后的实验报告默认用 Wireshark C 语言 socket那个年代的计算机网络实验绝大多数学校用的是 Wireshark 做协议分析用 C 语言在 Linux 或 Windows 下写 socket 程序。这不是随便选的。Wireshark 能直接看到 TCP 三次握手的每一个标志位socket 编程则逼着你手动处理字节序、地址结构体和缓冲区。这两样东西配合起来协议就不再是课本上的图而是你能改一个参数就观察到行为变化的东西。现在有人用 Python 的 scapy 或 socket 库替代效率更高但如果你要理解底层C 语言那套 struct sockaddr_in、htons、inet_pton 还是绕不过去。我一般建议抓包用 Wireshark写协议交互先用 Python 快速验证逻辑再回头看 C 版本对照理解内存布局。2.2 最小可复现环境搭建三台虚拟机就够不需要真实路由器也不需要公网 IP。用 VMware 或 VirtualBox 开三台 Linux 虚拟机一台做客户端一台做服务端一台做“中间人”跑抓包。网络模式选 Host-Only 或 NAT保证三台能互相 ping 通即可。具体步骤# 在服务端虚拟机上查看 IP确认网段 ip addr show | grep inet # 假设得到 192.168.56.101 # 在客户端虚拟机上 ping 服务端确认连通 ping -c 3 192.168.56.101 # 在第三台虚拟机上启动 Wireshark选择 Host-Only 对应的网卡 sudo wireshark逻辑说明Host-Only 模式让三台机器在同一个虚拟交换机下流量不会跑到物理网络抓包干净。参数上唯一要注意的是网卡名字Linux 下通常是 ens33 或 enp0s3选错了什么都抓不到。如果 ping 不通先检查防火墙sudo ufw status临时关闭用sudo ufw disable实验完再开回来。2.3 实验报告里最容易缺的一步时间同步与抓包过滤报告通常只写“启动 Wireshark 抓包”但没告诉你抓包过滤器怎么写。三台机器同时跑不设过滤会抓到大量无关流量。正确做法是在 Wireshark 的捕获过滤器里写host 192.168.56.101 and tcp port 8080只抓目标服务端的指定端口。另外虚拟机时间不同步会导致你按时间戳对不上客户端和服务端的日志。实验前统一执行sudo ntpdate pool.ntp.org或手动date -s对齐到同一分钟。这一步报告里基本不写但不做的话后面分析时序会非常痛苦。3. TCP 与 UDP 实验从代码到抓包结果的完整对照3.1 用 Python 写最小 TCP 回声服务端与客户端实验报告里的 C 代码往往几十行夹杂错误处理新手容易迷失。先用 Python 把逻辑跑通再对照 C 版本看差异。服务端# tcp_server.py import socket HOST 0.0.0.0 # 监听所有网卡方便虚拟机之间访问 PORT 8080 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 避免重启时端口占用 s.bind((HOST, PORT)) s.listen(1) print(fTCP server listening on {PORT}) conn, addr s.accept() with conn: print(fConnected by {addr}) while True: data conn.recv(1024) if not data: break conn.sendall(data) # 原样回发形成回声客户端# tcp_client.py import socket HOST 192.168.56.101 # 改成你的服务端 IP PORT 8080 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.connect((HOST, PORT)) s.sendall(bHello, TCP) data s.recv(1024) print(Received:, data.decode())逻辑说明SO_REUSEADDR是关键参数不加的话服务端每次重启都要等 60 秒 TIME_WAIT。recv(1024)的 1024 是缓冲区大小实验里发短消息够用但如果你要测大文件传输这个值会影响吞吐一般调到 4096 或 65536。客户端connect之后Wireshark 里应该立刻看到三次握手SYN、SYN-ACK、ACK。3.2 在 Wireshark 里验证三次握手与四次挥手启动抓包后运行客户端过滤tcp.port 8080。你应该看到序号方向标志位说明1客户端→服务端SYN客户端随机初始序列号2服务端→客户端SYN, ACK服务端确认并给出自己的序列号3客户端→服务端ACK握手完成4客户端→服务端PSH, ACK发送 “Hello, TCP”5服务端→客户端PSH, ACK回声数据6客户端→服务端FIN, ACK客户端请求关闭7服务端→客户端ACK确认8服务端→客户端FIN, ACK服务端关闭9客户端→服务端ACK最终确认如果只看到前三条没有后续数据检查客户端sendall是否执行、服务端recv是否阻塞在accept之前。常见翻车点是服务端防火墙没关SYN 到了但 SYN-ACK 被丢弃Wireshark 里只看到重传的 SYN。3.3 UDP 实验的差异点与抓包特征把上面代码的SOCK_STREAM改成SOCK_DGRAM去掉listen和accept服务端用recvfrom和sendto。UDP 没有握手客户端直接发服务端直接回。Wireshark 里过滤udp.port 8080你会看到每个数据包独立没有序列号确认机制。实验报告通常要求对比“丢包时 TCP 重传而 UDP 不重传”验证方法是在客户端连续发 100 个带序号的数据包服务端故意sleep或丢弃部分观察 TCP 版本会自动重传UDP 版本则永久丢失。这个对比是理解可靠传输最直观的方式。4. HTTP 与抓包分析把请求响应拆到字节级4.1 用 Python 构造原始 HTTP 请求并观察响应头实验报告里常有一个“手动构造 HTTP 请求”的环节但很多版本只让你用浏览器。更硬核的做法是用 socket 直接发原始文本# raw_http.py import socket HOST 192.168.56.101 PORT 80 request ( GET /index.html HTTP/1.1\r\n Host: 192.168.56.101\r\n Connection: close\r\n \r\n ) with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.connect((HOST, PORT)) s.sendall(request.encode()) response b while True: chunk s.recv(4096) if not chunk: break response chunk print(response.decode(errorsreplace))逻辑说明\r\n是 HTTP 协议规定的行结束符少一个\r或\n服务端可能直接返回 400。Connection: close告诉服务端发完就关这样recv循环才能靠连接关闭来结束否则会一直阻塞。参数上Host头在 HTTP/1.1 里是必须的没有它很多服务端返回 400。如果你在服务端虚拟机上跑一个简单的python3 -m http.server 80这个请求就能拿到目录列表。4.2 用 Wireshark 看 HTTP 请求的 TCP 分段在 Wireshark 里过滤http找到你的 GET 请求。展开 TCP 层你会看到请求可能被分成多个 TCP 段尤其是请求头较长时。实验报告里常问“为什么一个 HTTP 请求会对应多个 TCP 包”答案就是 MSS最大报文段长度限制。在以太网里 MSS 通常是 1460 字节超过就分段。你可以通过tcp.len字段看到每个段的数据长度。如果响应很大还会看到服务端连续发送多个段客户端逐个 ACK。这个观察能帮你理解“HTTP 是应用层协议实际传输靠 TCP 分段”这句话的真实含义。4.3 状态码与重定向的抓包验证在服务端放一个index.html再放一个redirect.html内容为meta http-equivrefresh content0;url/index.html。用浏览器访问redirect.htmlWireshark 里会看到两次 GET 请求。第一次返回 200 带 HTML 内容浏览器解析 meta 标签后发起第二次 GET。如果你用curl -v访问能看到更清晰的流程。实验报告里如果要求“分析重定向”记得区分 301/302 服务端重定向和 meta 刷新这种客户端行为前者在抓包里直接看到 301 响应和 Location 头后者只是普通 200 响应加一段 HTML。5. 避坑与排查实验报告里不会写的五个翻车点5.1 现象Wireshark 抓不到任何包接口列表为空原因Linux 下普通用户没有抓包权限或者选错了网卡。虚拟机里常有 ens33、lo、docker0 多个接口选到 lo 只能看到本地回环。解决用sudo wireshark启动或者在安装时配置dpkg-reconfigure wireshark-common允许非 root 抓包然后把用户加入 wireshark 组。选接口时先ip addr确认哪个接口有 192.168.56.x 的地址。5.2 现象TCP 客户端 connect 返回 Connection refused原因服务端没启动或者服务端绑定了 127.0.0.1 而不是 0.0.0.0。绑定 127.0.0.1 时只有本机可以连虚拟机之间连不上。解决检查服务端代码里HOST是否为0.0.0.0用ss -tlnp | grep 8080确认监听地址是0.0.0.0:8080而不是127.0.0.1:8080。如果服务端在 Windows 上还要检查 Windows 防火墙是否放行。5.3 现象UDP 服务端收不到数据但客户端 sendto 没报错原因UDP 是无连接的sendto成功只表示数据交给了本地协议栈不代表对方收到。常见原因是服务端recvfrom的缓冲区太小或者服务端绑定的端口和客户端发送的端口不一致。解决在服务端打印recvfrom的返回值和来源地址确认数据到了。如果没到在中间人虚拟机上用tcpdump -i any udp port 8080 -X看数据包是否出现在网络上。5.4 现象HTTP 请求返回 400 Bad Request原因请求行或请求头格式错误最常见的是行结束符用了\n而不是\r\n或者Host头缺失。解决用print(repr(request))把请求字符串打印出来逐字节检查。\r\n在 Python 字符串里必须写成\r\n不能写成\\r\\n。另外请求行末尾和最后一个头之后必须有一个空行也就是连续两个\r\n。5.5 现象实验报告里的结果和你的抓包对不上序列号或窗口大小不同原因不同操作系统、不同内核版本的 TCP 初始序列号随机算法和窗口缩放因子不同。2015 年的报告可能基于 Windows 7 或 Ubuntu 14.04你现在用 Windows 11 或 Ubuntu 22.04默认参数已经变了。解决不要死磕具体数值关注相对变化。比如三次握手的标志位顺序、重传的超时时间倍增规律、窗口大小随接收缓冲区的变化趋势这些是稳定的。如果报告里写了具体序列号那只是示例你的环境里一定是不同的随机值。6. 把实验报告变成可复用的调试脚本一个自动化验证技巧实验报告做完就扔下次遇到网络问题还是从头抓包这是最大的浪费。我习惯把每个实验的核心验证逻辑写成一个可重复运行的脚本放在~/netlab/下用 Makefile 串起来。比如 TCP 回声测试写一个check_tcp.sh#!/bin/bash # check_tcp.sh - 自动验证 TCP 回声服务是否正常 SERVER_IP${1:-192.168.56.101} PORT${2:-8080} # 启动服务端后台 python3 tcp_server.py SERVER_PID$! sleep 1 # 运行客户端并捕获输出 OUTPUT$(python3 tcp_client.py 21) echo $OUTPUT # 验证是否收到回声 if echo $OUTPUT | grep -q Received: bHello, TCP; then echo [PASS] TCP echo works else echo [FAIL] TCP echo broken fi kill $SERVER_PID逻辑说明${1:-默认值}是 bash 的参数默认值语法不传参就用默认 IP 和端口。sleep 1给服务端启动留时间虚拟机慢的话调到 2。grep -q静默匹配只靠退出码判断。这个脚本可以扩展成测试 UDP、HTTP、甚至模拟丢包。参数上如果你在 CI 里跑把sleep换成轮询ss -tln检查端口是否监听更可靠。更进一步用tcpdump在后台抓包脚本结束时自动生成 pcap 文件配合tshark命令行分析# 后台抓包只抓 8080 端口最多 100 个包 sudo tcpdump -i any -w /tmp/tcp_echo.pcap -c 100 port 8080 TCPDUMP_PID$! # ... 运行测试 ... kill $TCPDUMP_PID # 用 tshark 统计握手次数 tshark -r /tmp/tcp_echo.pcap -Y tcp.flags.syn1 and tcp.flags.ack0 | wc -l这个技巧的价值在于下次你换了一台机器、换了一个内核跑一遍脚本就知道协议行为有没有变化。实验报告里的结论是静态的但你的验证脚本是活的。我自己的习惯是每做完一个实验就把关键命令和预期输出写进脚本注释里半年后回头看比翻报告快得多。希望帮到你。本文还有配套的精品资源点击获取