4. 观察TCP序号与确认号的变化规律
任务目标
使用Wireshark抓取一次TCP连续数据传输过程,跟踪报文段中序号(Seq)与确认号(Ack)的递增关系,验证TCP可靠传输中序号机制的工作方式。
环境准备
- 安装Wireshark(版本≥3.0)
- 本机回环接口(lo/Loopback)即可完成,无需额外网络设备
- Python 3(用于生成可控的连续TCP数据流)
抓包与数据生成
为便于观察序号递增规律,使用Python在本地建立TCP客户端与服务器,传输一段已知长度的数据(例如20000字节)。回环接口抓包可避免网络噪声干扰,且序号变化清晰可追踪。
服务端脚本(server.py):
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('127.0.0.1', 9999))
s.listen(1)
conn, addr = s.accept()
total = 0
while True:
data = conn.recv(4096)
if not data:
break
total += len(data)
conn.close()
s.close()
print(f"received {total} bytes")
客户端脚本(client.py):
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1', 9999))
payload = b'x' * 20000
s.sendall(payload)
s.close()
抓包步骤
- 启动Wireshark,选择回环接口(Loopback: lo),开始抓包。
- 先运行
python server.py,再运行python client.py。 - 传输完成后停止抓包,在过滤栏输入
tcp.port == 9999过滤出本次连接的所有报文。
序号与确认号分析
在Wireshark中依次点击每个TCP报文,观察Sequence Number与Acknowledgment Number字段。以下为关键观察点:
- 三次握手阶段:SYN报文消耗一个序号,SYN-ACK的确认号=客户端初始序号+1。
- 数据发送阶段:每个数据报文的
Seq等于上一个数据报文的Seq + 上一个报文携带的字节数(Len列)。 - ACK确认:接收方返回的
Ack等于期望收到的下一个字节序号,即最后收到的Seq + Len。 - 连续传输:若发送窗口足够,发送方无需等待每个ACK即可连续发送多个报文段,但每个报文的Seq仍严格按字节偏移递增。
以下为20000字节数据在回环接口传输时,抓包中前几个数据报文段的预期序号变化(MSS=16384,回环接口单段可承载全部数据):
# 方向: 客户端 → 服务器
报文1: Seq=1, Len=16384, Ack=1
报文2: Seq=16385, Len=3616, Ack=1
# 方向: 服务器 → 客户端(ACK确认)
报文3: Seq=1, Ack=20001, Len=0
其中Ack=20001表示服务器已正确收到序号1~20000的全部字节,期望下一个字节序号为20001。若数据被拆分为多个TCP段(如MSS较小),则每个段的Seq依次为1, 1+MSS, 1+2*MSS, ...,ACK始终指向最后收到的Seq+Len。
验证方法
- 在Wireshark中启用Sequence number列显示(默认已显示)。
- 选中任意数据报文,查看其
Seq值,再选中下一个数据报文,确认其Seq= 前一个Seq+ 前一个Len。 - 找到接收方返回的纯ACK报文(Len=0),确认其
Ack= 最后一个收到的数据报文Seq + Len。 - 若传输过程中无重传,所有数据报文的Seq应严格单调递增,且相邻差值等于前序报文的Len字段。
通过条件:上述序号与确认号的数值关系在抓包中完全吻合,且最终ACK的确认号等于20001(即初始序号1 + 20000字节),说明序号机制按预期工作。
常见问题
- 看到Seq不是从1开始:Wireshark默认显示相对序号(Relative Sequence Number),即减去初始ISN后的值。如需查看原始序号,右键点击列头选择Protocol Preferences → TCP → 取消勾选Relative Sequence Numbers。
- 出现Seq跳变:若抓包中看到Seq不连续,可能是存在重传或乱序,此时应检查是否有TCP Retransmission标记。
- 回环接口数据量小:若一次sendall被内核拆分为多个TCP段,只需按上述规则逐段验证即可,不影响结论。
上图展示了本次抓包中三个关键报文的序号流动方向。实际抓包中报文数量可能更多(取决于MSS与窗口大小),但序号与确认号的递增规则完全一致:每个数据报文的Seq等于已发送字节总数+1,每个ACK的Ack等于已接收字节总数+1。