计算机网络 03:抓包能证明什么
抓包文件里有一个确认号覆盖了请求的全部字节,能否据此认定服务端已经处理请求?不能。这个确认号属于 TCP 的接收状态;业务处理发生在应用读取、解析和执行之后。要回答“请求停在哪里”,必须把报文记录与端点日志放到同一条有边界的证据链上。
第 02 篇已经定义四字节长度头和有界消息体。本篇沿用该格式,只发送合成字符串 network-03,观察应用调用、连接端点与序号之间的关系。实际环境完成了回环回显和序号手算,但抓包设备权限不足,未取得真实 pcap;下文把已运行的部分、可复跑的捕获步骤和未验证结论分别标出。
报文记录首先属于一个捕获点
应用调用 sendall,数据进入传输实现;抓包程序在操作系统提供的捕获接口观察记录;接收应用再调用 recv,取得可读字节。这些事件并不是同一个事件的不同显示方式。一个观察点缺少另一个观察点的信息,不能靠增加输出字段补齐。
1 | |
图中只表示观察关系,不承诺所有系统内部函数的调用顺序。回环交换不经过物理以太网链路,因此本篇不验证网卡发送、交换机转发或路由器行为。对物理接口的捕获,驱动、卸载和捕获钩子的位置又会影响所见记录。
完整说明一次捕获,至少需要接口、过滤表达式、开始与结束条件、保存长度和工具版本。只提供一张有红色提示的截图,无法知道握手是否早于捕获开始、是否抓错接口、是否截短了包,也无法知道筛选条件隐藏了哪些报文。
抓包文件还有自己的链路类型。不能因为讨论的是 TCP,就固定跳过十四字节“以太网头”后解析 IP。官方定义的 LINKTYPE_NULL 使用四字节主机字节序协议族头,后面才是载荷;实际文件采用什么格式应从文件元数据读取,不能把某个平台的回环格式泛化到所有系统。
过滤减少范围,也限制结论
捕获过滤器在收集阶段决定哪些记录进入文件。分析器的显示过滤器则从已有记录中选择展示内容。两者发生在不同阶段:显示过滤可以撤销,捕获阶段没有保存的字节不能事后恢复。
本篇只允许观察自建服务。先让脚本绑定 127.0.0.1 的临时端口,再把日志中的端口填入过滤表达式,既缩小噪声,也避免收集其他服务流量。监听端口由运行中的 socket 保持占用,不通过“寻找空端口后关闭它”的方式留下竞争窗口。
1 | |
脚本打印 listener_ready 后等待回车。在另一个终端读取该次端口,设置 PORT,再启动捕获。以下是 macOS lo0 接口的命令模板;其他系统必须使用已核实的回环接口名。
1 | |
只有具备相应权限的自建实验环境才执行此命令。本次没有执行 sudo、安装权限辅助程序或改变捕获设备权限。捕获程序报告开始监听后,回到脚本终端按回车;交换完成后在捕获终端按 Ctrl-C,保留退出计数,再读取文件。
1 | |
-i 选择接口,-w 写原始捕获文件,-r 读取文件,-S 显示绝对 TCP 序号。这里用上游文档明确记载的 -n 禁止地址和端口等名字转换,不把不同版本的 -n、-nn 用法差异写成普适规则。
当次核查的上游 tcpdump 4.99.5 手册规定,-s 0 恢复默认 262144 字节捕获长度。它不是无限长度,也不能据此保证任何记录都不会截短。本机工具报告 tcpdump 4.99.1、Apple 161、libpcap 1.10.1;上游手册与本机版本分开记录,选项语义和实际截断状态仍需结合本机手册与文件检查。
用字节范围关联日志
附件脚本复用第 02 篇的 framing.py,先建立本机 TCP 连接,记录客户端与服务端的地址、端口,然后发送一条消息。脚本是有限单次交换,故意先完成客户端小消息写入,再调用服务端读取;这给“发送返回时应用尚未读取”提供明确的程序顺序。
network-03 是十个 ASCII 字节,加四字节长度头后,提交给 TCP 的数据共十四字节。编码为:
1 | |
服务端每次最多读取五字节,解析器跨读取保留状态,得到完整十字节消息后原样回显。客户端再次解析并比较消息。读取日志里的块大小是应用观察,不是分段方式;不能根据三次 recv 推断线上必有三个 TCP 段。
关联真实捕获时,先用地址、端口和方向确定连接,再在每个方向累计数据字节范围。应用帧的四字节头同样属于 TCP 数据,不能只数十字节业务字符串。发生重传时,相同序号范围可能重复出现,也不能把所有包长直接相加当作应用新收到的数据量。
时间只用于辅助定位。脚本同时记录单调时钟和墙上时钟:单调时钟适合同一进程内比较事件间隔;捕获工具的时间戳应先核对时钟来源与精度,不能把两个不同来源的数值直接相减。日志记录发生在调用前后,它也不是内核处理的精确瞬间。
本次脚本运行获得 sendall_return、server_message_decoded、client_reply_verified,最后记录本地交换完成。附件保留原始日志。它证明本机端点最终解析出相同消息,不证明抓包链路完整,也不证明数据何时被 TCP 确认。
相对序号和确认号的含义
Wireshark 默认相对显示 TCP 序号和确认号,便于阅读长整数。显示为零的 SYN,不表示线上序号字段真的为零;它只是分析器选择了相对起点。中途开始捕获时,显示起点也不能证明已经观察到连接建立。
RFC 9293 §3.4按字节组织序号空间。每个数据字节占一个序号;SYN 和 FIN 各自也占一个序号,纯 ACK 不占。序号运算按模 2^32 进行。为了先排除回绕影响,设一个教学连接的初始序号是 1000。
| 教学发送事件 | SEQ | 数据字节 | 控制位占用 | 连续范围之后的下一序号 |
|---|---|---|---|---|
| SYN | 1000 | 0 | 1 | 1001 |
| 本篇完整帧 | 1001 | 14 | 0 | 1015 |
| 纯 ACK | 1015 | 0 | 0 | 1015 |
| FIN | 1015 | 0 | 1 | 1016 |
这张表是手算输入,不是本次抓包结果。附件运行了对应断言,并额外检查 2^32 - 2 后连续四字节的下一序号为 2。它验证算术和教学约定,未验证任何内核发送的实际字段。
累计确认号 X 表示接收端下一期待的序号,确认了 X 之前连续收到的序号范围。对上表连续、无缺口的数据而言,确认号 1015 覆盖十四字节帧;但不能进一步推出服务端已经调用 recv、通过长度校验或执行业务。
公式 下一序号 = SEQ + 数据字节数 + SYN占用 + FIN占用 描述该连续范围的右边界,不保证每个报文都会立即触发一个等于此值的 ACK。存在缺口、重复数据、延迟确认等条件时,观察到的确认行为需要额外状态。把所有数据段统一加一,会把 SYN/FIN 的特殊占用错误地加到普通数据上。
分析器提示不是独立的故障结论
Wireshark 的 TCP 分析依赖捕获文件中已经出现的记录及其顺序。例如“Previous segment not captured”的判断使用当前序号与下一预期序号的关系。这个提示首先表明当前记录序列缺少某个范围;缺失可能发生在网络,也可能发生在捕获机制、过滤过程或开始时间之前。
tcpdump 的退出计数同样要按定义读。captured 是程序接收处理的数量;received by filter 的具体含义依赖操作系统;dropped by kernel 反映抓包机制因缓冲等原因丢弃的记录,不能直接当作网络丢包量。操作系统未报告这类信息时,零也不能证明捕获完整。
发送方向出现校验和异常提示,还要考虑校验和卸载:捕获可能发生在网卡补齐校验和之前。分段或聚合卸载也可能让捕获记录大于通常预期的链路 MTU。因而一个大记录不自动对应链路上的一个等长帧,一个异常校验和也不自动证明线上损坏。
本次没有物理网卡捕获,也没有修改卸载开关,以上属于官方文档支持的解释条件。若要证明某次故障,需要记录捕获位置,并与另一端证据或受控对照关联;不能看到“可能是卸载”就反向断言卸载一定是原因。
运行结果与未完成的捕获验收
脚本只使用 Python 标准库,但依赖本系列第 02 篇的帧解析模块。在仓库中可直接运行;单独下载时,把 framing.py 与脚本放在同一目录,也能按 Python 模块搜索规则导入。
1 | |
本次 Python 3.14.4、Darwin 27.0.0 arm64 环境中的回显和手算断言通过。捕获权限探测则先建立独占的回环监听端口,再使用 dumpcap 对该端口执行一秒捕获,结果退出码为 1,报告无法打开 /dev/bpf0。原始错误见附件,没有补造 pcap 文件或把其他流量当作本次实验。
因此,计划要求的“调用日志与报文对齐”只完成端点侧准备,包级对齐仍待有捕获权限的隔离环境执行。补证时应保存原始 pcap、退出计数、端点日志和工具版本,核对十四字节请求及对应回复;不能只保存一张显示确认号的截图就把验收标记为完成。
附件:实验脚本、本次端点日志与手算结果、捕获权限原始错误。帧模块位于第 02 篇的附件中。
练习
序号练习。 假设 SYN 的绝对序号为 9000,之后连续发送二十字节普通数据,再发送 FIN。分别给出数据起点、数据后的下一序号和 FIN 后的下一序号。
核对:数据从 9001 开始,数据后的下一序号为 9021,FIN 后为 9022。若二十字节拆成两个十字节段,第二段从 9011 开始;拆段不增加应用数据的序号占用。
证据练习。 抓包可见覆盖完整请求的累计 ACK,但应用日志没有“解析完成”。列出两种仍然可能的状态,以及一种能区分它们的新增观察。
核对:应用尚未读取,或者已读取但解析失败,都与这个 ACK 相容。增加接收返回和解析结果日志可以区分这两种状态;只有发送端抓包不能直接回答服务端业务是否提交。
一手资料
以下资料于 2026-09-19 写作当次核查。上游版本说明与本机实测分别使用,不用文档代替尚未成功的抓包。
- tcpdump 官方 4.99.5 手册源文件:捕获选项、保存长度和退出计数。
- Wireshark 相对序号说明:显示值与绝对序号的区别。
- Wireshark TCP Analysis 与卸载说明:分析器判据与捕获位置限制。
- LINKTYPE_NULL 官方格式:回环记录的格式示例,实际链路类型必须读取文件确认。
- RFC 9293 §3.4:序号空间、累计确认及 SYN/FIN 的序号占用。




