
简介这是东南大学自动化学院「信息通信网络概论」课程第四次实验报告主题为基于 TCP/IP 与 UDP/IP 的计算机网络通信应用程序设计适合正在学习网络编程、WinSock 接口或需要完成同类实验的本科生参考。报告按课程要求完整记录了实验目的、原理、方案步骤、设备配置、运行记录与总结并附有部分核心代码涵盖客户机/服务器工作流程、套接字创建与绑定、监听与连接、消息发送接收等关键环节同时展示了界面设计、功能描述以及获取主机名、发送时间和自定义字符画等改进点。资源为 PDF 格式共 1 个文件压缩包大小约 20KB内容精炼便于对照实验要求快速复习或撰写自己的实验报告。目前已有 87 人学习/下载适合东南大学相关专业学生或需要理解 TCP/UDP 通信编程实践的同层次读者。1. 计算机网络实验报告拉开差距的地方不在截图在能把报文里的数字说圆计算机网络实验写到第四次主题基本绕不开传输层用抓包工具把一条 TCP 连接的完整生命周期拆开验证三次握手、四次挥手、MSS 协商和校验和计算最后把过程写进一份 PDF 实验报告交付。像东南大学这类把协议分析排进实验课的高校批注往往集中在同一个地方——截图没少贴但第二次握手的 ack 为什么是 1校验和为什么显示 unverified全没答出来。这种报告被退回重写是大概率事件缺的不是流量而是不知道把注意力放在哪些字段上。下面按实验的先后顺序把抓包环境、过滤器、握手挥手的字段变化、HTTP 切片和校验和验证一条线讲下来保证写进报告里的每个数字都能当场复现。2. 抓包环境与过滤器设置让实验报告可复现的前提2.1 抓包后端选 Npcap回环接口产出可控流量Wireshark 在 Windows 上的抓包后端默认是 Npcap安装时不需要再选 WinPcap。如果你照着旧教程装了 WinPcap在 Win10 以上系统里抓包会频繁遇到找不到接口、权限不足或者回环流量抓不到的问题先卸掉重装。Npcap 安装向导里有一个关键选项支持 loopback 抓包。不勾选的话选择回环接口能看到接口存在但一个包都收不到别在这一步浪费半小时。要产生一条受控的、不含杂音的 TCP 流最省事的路径是本机回环。开一个 Python 内置 HTTP 服务再用浏览器访问一次python3 -m http.server 8080 --bind 127.0.0.1--bind 127.0.0.1让服务只监听回环地址不会暴露到局域网也避免防火墙弹窗和背景扫描流量干扰抓包结果。浏览器访问http://127.0.0.1:8080/后在 Wireshark 里选择 Npcap Loopback AdapterLinux 对应 lo开始捕获访问结束停止抓包就能在列表里看到一条127.0.0.1 → 127.0.0.1的完整 TCP 流。下面的接口选择表可以原样写进实验报告的实验环境小节抓包点用在哪一步要注意的坑Npcap Loopback / lo本机 HTTP 服务观察状态机必须勾选 Npcap 的 loopback 支持物理网卡访问公网测试服务器Windows 下需管理员权限开启混杂模式Wi-Fi 接口无线重传、弱网场景驱动不支持 monitor 模式时只能看到收发包2.2 捕获过滤器与显示过滤器语法完全不在一个体系抓包开始前用捕获过滤器开始之后用显示过滤器。前者是 BPF 语法在数据包进入缓冲区之前就执行不匹配的报文直接丢弃作用在驱动层后者是 Wireshark 的字段表达式作用在已经落盘的 pcap 文件上只是隐藏显示不丢数据。实验里的惯用做法是捕获阶段放宽条件分析阶段再精确缩小范围。下面的表格对比了两者的差异类型作用时机常见写法用途示例BPF 捕获过滤器写包进 pcap 之前tcp port 8080、host 127.0.0.1只保留 8080 端口流量显示过滤器pcap 落盘之后tcp.stream eq 0、http.request定位某一条 TCP 连接很多第一次做实验的人把tcp.stream eq 0直接粘进捕获过滤器输入框提示语法错误或者明明有流量但一个包都抓不到。原因就是捕获过滤器里没有tcp.stream这个字段也没有eq。两个输入框长得再像背后的语法体系也不同这个区别写进报告能避免被追问时卡壳。2.3 用 tshark 先确认抓到的流量再截图在截实验图之前我会先用 tshark 把抓包文件里的 HTTP 请求拉出来看一眼确认流量是实验真正要的tshark -r 4.pcapng -Y http.request -T fields -e frame.number -e ip.src -e ip.dst -e http.request.uri -E headery-r指定读取的抓包文件-Y是显示过滤器-T fields让输出变成纯字段模式-e声明要打印的字段-E headery在首行输出字段名。执行后能看到每个 HTTP 请求的包号、源地址、目的地址和 URI几秒钟就能判断这次实验访问了几次服务、每个请求都到达了应用层。这个输出比截图更适合直接贴进实验报告附录。3. 三次握手与四次挥手的报文级拆解seq、ack、SYN/FIN 怎么对得上3.1 用 tcp.stream 锁定一条完整连接无论课程用的是谢希仁教材还是《计算机网络自顶向下方法》的 Wireshark Lab这一节对照的报文结构都是同一套。在抓包列表里任意 HTTP 请求上右键选择 Follow → TCP StreamWireshark 会弹出按顺序排列的应用层数据视图对话框顶部就是这条流对应的过滤器通常是tcp.stream eq 0。把这串字符复制到主界面的显示过滤器里剩下的事务都限定在这条 TCP 连接上从第一个 SYN 到最后一个 FIN 一个不多一个不少。需要生成实验报告里最常用的时序图时用 Statistics → Flow Graph在过滤器栏填入tcp.stream eq 0图表会按时间顺序画出两个方向的箭头和 Flags 注记。这张图比主窗口截图直观得多三次握手和四次挥手各占几个包、谁是主动关闭方一眼就能讲清。3.2 相对序号与绝对 ISN报告里最容易写反的两个数Wireshark 默认把 Sequence number 显示为相对值第一次握手 seq0第二次握手 seq0、ack1第三次握手 seq1、ack1。下面是一次回环抓包的标准输出包方向Flagsseq相对ack说明127.0.0.1:52190 → 127.0.0.1:8080SYN00客户端发起连接127.0.0.1:8080 → 127.0.0.1:52190SYN,ACK01服务端确认宣告自己的初始序号127.0.0.1:52190 → 127.0.0.1:8080ACK11双向同步完成连接建立规律只有一条SYN 和 FIN 各占一个序号。收到带 SYN 的包ack 就等于对方当前 seq 加一收到带 ACK 的包自己的 seq 也往前走一。报告里绝大多数分析用相对序号讲逻辑就够但如果你想论证初始序号是随机的必须到 Preferences → Protocols → TCP 取消 Relative sequence numbers再看真实 ISN——通常是几亿级别的随机数把两个视角都写进去报告的说服力完全不同。3.3 MSS、Window Scale、SACK 的协商位从哪读展开第二个包SYN,ACK的 TCP Options能看到三个高频协商项MSS、Window scale、SACK permitted。MSS 是 1460表示对端通告自己接收的 TCP 数据段最大为 1460 字节这直接对应后面要讲的 MTU 计算。Window scale 的值是 7意思是 TCP 头里 16 位窗口字段要左移 7 位才是真实接收窗口比如窗口字段显示 64240实际窗口是 64240 7约 8.2 MB这是高带宽链路必需的扩容机制。SACK permitted 置位说明两端都同意用选择性确认容忍乱序与局部丢包。这些选项在教材上往往只有一两句话实验报告把各自对应的包序号、字段值、计算后的结果列成一张表就能把对 TCP 扩展选项的理解写扎实。注意选项只在 SYN 和 SYN-ACK 里协商后续数据包可能不带全别在普通数据包里翻选项自找困惑。3.4 挥手报文与 TIME_WAIT 的抓包验证连接断开时看最后四个包主动关闭方发 FIN对端回 ACK对端再发 FIN通常带 ACK主动方回最后一个 ACK。关键点在主动关闭方发出最后那个 ACK 之后本机 TCP 进入 TIME_WAIT 状态等待 2 个 MSL保证最后一个 ACK 有重发的机会也让旧连接的重复分组在网络中自然消亡。抓包结束后在操作系统里能直接看到这个状态。Linux 上ss -tan | grep -E TIME-WAIT|FIN-WAITWindows 用netstat -ano | findstr TIME_WAIT。ss -tan列出当前所有 TCP 连接状态grep 过滤出 TIME-WAIT 和 FIN-WAIT 的行。在本机启动的 Python HTTP 服务场景里谁是主动关闭方取决于哪一端先调 close如果是浏览器发起请求通常是浏览器侧进入 TIME_WAIT。把这条命令的输出和 Wireshark 里的最后一个 ACK 对应起来挥手这一节的证据链就完整了。4. HTTP 请求的 TCP 层切片MSS 计算、Content-Length 核对与 CRC 的坑4.1 从 HTTP 请求往下钻到 TCP 分段在显示过滤器里输入http.request列表里只剩请求报文。右键选中一条 GETFollow → HTTP Stream 看到的是应用层完整的请求和响应Follow → TCP Stream 看到的则是这条 HTTP 消息在传输层被切成的若干 TCP 分段。这一步是理解HTTP over TCP的关键应用层一次 write 出几百上千字节传输层按 MSS 拆成多个段逐个发送抓包里每个段都是独立报文。实验报告里可以写清这一层的观察响应共 3 个 TCP 分段第一个带 HTTP 头第二、三个是 body 剩余部分判断依据是每个段的tcp.len都不超过 MSS 1460 字节。这句话写出来比你贴十张 TCP 详情截图都管用。4.2 MSS 与 MTU 的计算关系MSS 不是随便协商出来的它受物理链路 MTU 约束。以太网 MTU 是 1500IP 头通常 20 字节TCP 头通常 20 字节1500 - 20 - 20 1460这就是 MSS 的典型来源。如果 TCP 头带了时间戳等选项TCP 头变成 32 字节实际数据上限会小于 1460这时要以三次握手 SYN 包里的 MSS 选项值为准。属性数值含义MTU1500 字节IP 层单包上限链路层决定IP 头20 字节不含选项的标准 IPv4 头TCP 头20 字节不含选项的标准 TCP 头MSS1460 字节1500 - 20 - 20TCP 数据段上限报告里最常见的错误是把 MSS 写成 MTU。一句话区分MTU 是 IP 层约束MSS 是 TCP 层约束MSS 约等于 MTU 减 IP 头减 TCP 头。把这个等式和抓包里的 MSS 字段对照写属于必得分。IP 分片之所以在这个实验里几乎看不到正是因为两端通过 MSS 协商避免了 TCP 数据触发 IP 分片UDP 没有类似协商才需要 IP 层做分片。4.3 用 Content-Length 和 tcp.len 核对传输完整性响应头里的 Content-Length 是应用层给出的 body 总长度TCP 层每个携带数据的包都有tcp.len字段。把流内所有tcp.len累加结果应该等于 Content-Length。用 tshark 可以一行算出来tshark -r 4.pcapng -Y tcp.stream0 tcp.len0 -T fields -e tcp.len | awk {s$1} END {print s}这里tcp.len0过滤掉纯 ACK 包-e tcp.len只输出每个有效负载段的长度awk 累加后打印总和。把这个求和结果和 HTTP 响应头里的 Content-Length 对比一致就说明这次传输数据无丢失、无重复不一致则正好在报告中展开重传或乱序的讨论。Windows 系统没有 awk 的话用 WSL 或 Git Bash 运行这一行。4.4 为什么报文里看不到以太网 CRC/FCSCRC 校验怎么从报文里观察是个高频疑问答案是以太网的 CRC 观察不到。帧尾的 FCS 是 32 位 CRC由发送网卡在物理层计算并追加接收网卡验完立即剥除Wireshark 拿到的是验证之后的帧所以 Frame 层级里没有 FCS 字段。能从抓包字节里自己验证的是 IP 头里的 Header checksum 和 TCP 头的 Checksum这两者由协议栈或网卡在抓包点附近写入也正是下一章手动重算的对象。5. 校验和验证与重传观察把报告里的数字重算一遍5.1 IP Header Checksum 怎么验证标准 IPv4 头是 20 字节不含选项Header checksum 的计算范围就是这 20 字节。算法是把校验和字段先置零然后按 16 位一组反码求和再把结果取反填入。Wireshark 里展开 IPv4 层通常看到Header checksum: 0x9d84 [validation disabled]说明默认没开校验选项。在 Edit → Preferences → Protocols → IPv4 勾选 Validate checksum重新打开抓包文件每个包会显示 valid 或 invalid前者代表计算通过。注意 IP 头校验和只覆盖 IP 头本身不保护数据部分。真正验证 TCP 数据正确性的是下面要讲的 TCP 校验和实验报告的重心应当放在 TCP 这一层。5.2 TCP Checksum、伪头部与 unverified 之谜TCP 校验和的计算范围除 TCP 头和数据之外还带一个 12 字节的伪头部依次是源 IP 地址、目的 IP 地址、保留字节、协议号 6、TCP 报文段总长度。伪头部的设计目的是把 IP 层的关键信息也纳入校验防止数据被发往错误目的地。抓包里 TCP 校验和显示为 unverified 时不要先怀疑抓包工具多数情况是网卡开启了 checksum offload抓包点拿到的报文校验和尚未由网卡硬件填充或者已经被网卡接管Wireshark 无法确认真实值只能标 unverified。软件层面可以尝试在 Preferences → Protocols → TCP 勾选 Validate the TCP checksum if possible看能否得到 valid驱动层面可以用 ethtool 关闭发送 offloadethtool -K eth0 tx off-K表示修改网卡 offload 能力tx off把发送校验从网卡卸载移回内核协议栈。该命令需要 root 权限且部分驱动不支持执行后会提示 no offload features。实验报告里更合适的处理方式是明确写上网卡硬件校验卸载导致抓包点未包含最终校验值不表示数据损坏硬把 unverified 改成 valid反而歪曲了抓包事实。5.3 用 Python 对一个抓包重算 TCP 校验和让报告从截图搬运升级到数据复算的关键是亲手动笔算一次校验和。下面这段代码用 Scapy 读取 pcapng对回环接口抓到的第一个 TCP 段做完整验证import socket import struct from scapy.all import rdpcap, IP, TCP def checksum16(data): if len(data) % 2: data b\x00 words struct.unpack(!%dH % (len(data) // 2), data) s sum(words) s (s 16) (s 0xffff) # 高16位进位回卷 s s 16 # 再回卷一次 return ~s 0xffff def tcp_checksum(src, dst, tcp_bytes): # 伪头部4字节源IP 4字节目的IP 1字节0 1字节协议号6 2字节TCP长度 pseudo struct.pack(!4s4sBBH, socket.inet_aton(src), socket.inet_aton(dst), 0, 6, len(tcp_bytes)) # 把TCP头的校验和字段(偏移16-17)清零 zeroed tcp_bytes[:16] b\x00\x00 tcp_bytes[18:] return checksum16(pseudo zeroed) pkts rdpcap(4.pcapng) pkt next(p for p in pkts if IP in p and TCP in p) seg bytes(pkt[TCP]) print(报文里存的校验和: 0x%04x % pkt[TCP].chksum) print(手工重算: 0x%04x % tcp_checksum(pkt[IP].src, pkt[IP].dst, seg))rdpcap解析 pcapng 后bytes(pkt[TCP])取出的就是从 TCP 头到 payload 结尾的原始字节zeroed把校验和字段所在的两字节偏移 16 到 17清零伪头部按!4s4sBBH被打包成 12 字节。运行后两个十六进制数一致说明该 TCP 段通过校验。若不一致优先检查抓包文件是否被截断、是否在支持 offload 的环境下采集。把这段代码放进报告的校验和验证小节附上对应包的 frame.number可信度立刻不同。5.4 重传与快速重传的观察点TCP 的可靠性最终落在重传上。显示过滤器输入tcp.analysis.retransmissionWireshark 会标出所有重传包输入tcp.analysis.duplicate_ack能看重复 ACK。两种重传要能区分开重传类型触发条件常见场景RTO 超时重传超时定时器到期报文丢失、链路拥塞、RTT 骤然变大快速重传收到 3 个重复 ACK单包丢失但后续数据仍在到达如果报告里只写TCP 会重传基本没有信息量能贴出 Time-Sequence 图并指出某个点发生了快速重传才算看懂可靠性机制。图的位置在 Statistics → TCP Stream Graphs → Time-Sequence(Stevens)横轴时间、纵轴序号纵坐标出现跳变的点就是重传或乱序的现场配合 RTT 图一起贴这一小节能写得很扎实。6. 用 tshark 字段导出反向校核报告数据交报告之前最值得跑的一步是把报告里要写的关键字段一次性导出成 CSV逐栏和文档里的数字比对而不是对着截图用肉眼数。用下面的命令tshark -r 4.pcapng -Y tcp.stream0 -T fields \ -e frame.number -e frame.time_relative \ -e ip.src -e ip.dst -e tcp.srcport -e tcp.dstport \ -e tcp.seq_raw -e tcp.ack_raw -e tcp.flags.str -e tcp.len \ -E headery -E separator; report_data.csvtcp.seq_raw和tcp.ack_raw输出绝对序号不再受相对序号设置影响正好用来核对报告里的 ISN 和 ack 递推tcp.flags.str输出 SYN、SYN,ACK 这类可读标记因为标记里自带逗号所以这里用-E separator;做分隔Excel 导入时选分号即可。导出之后做三个快速自检。第一握手里 SYN 只出现一次SYN,ACK 也只出现一次第二除握手外所有tcp.len之和必须等于 HTTP 响应 Content-Length第三挥手阶段收到 FIN 后回复的 ACK其 ack 号必须等于 FIN 的 seq 加一。三个条件都满足报告里的核心数字就站得住。如果发现 flag 分布和预期不符多半是抓包期间有其他进程扫过同端口删掉该流重新抓一轮比在报告里硬解释来得划算。核对时优先盯frame.number列报告里每出现一个 seq 或校验和就顺手把包号标在旁边的括号里评阅人拿同一份 pcapng 按包号定位报告里的每个结论都能当场对上。本文还有配套的精品资源点击获取