Wireshark 网络包分析实战五:seq/ack在TCP通信不同阶段的数值关系

Overview

  • 当我们说,TCP是可靠的,我们在表达什么? 或者说,TCP协议是怎么保证可靠的?

实现机制其实非常简单,就是靠ack与seq机制,我们直接看TCP Header。

也就是Sequence Number和Acknowledgment Number。TCP的通信与HTTP不通,它并不是一个请求对应一个响应,为了加快传输的效率(因为一来一回就是一个RTT啊),TCP的通信机制允许一次发送多个数据包,然后多个发送包可以对应一个响应包,也就是所谓ACK包。

那TCP到底如何保证发送的数据被接收到了呢?就是靠接收方返回的数据包中的ack字段。

比如ack=1000,接收方告诉发送方:嗨,老兄。你刚才发了很多数据嘛,我跟你讲,1000字节以前的数据我都收到了,下次发送就从1000字节开始发哈。

seq和ack就是这么重要。下面让我们学习一下在TCP通信的不同阶段,它们之间可能都有什么数量关系吧~

Example

Three-way Handshake

在三次握手和四次挥手的过程中,没有应用层数据,即有效载荷为0.

但是三次握手中的SYN标志、四次挥手的FIN标志都算作:载荷为1,即实际上Len=1。

眼见为实,以三次握手为例:

我们看30号包:seq=0,载荷TCP Len 也为0,但31号包是怎么说的?

31号包的ACK=1,好比30号包发送了1 byte的数据。

但30号包真的没有携带

1、TCP Len 显式为0

2、IP包显式长度为60。Length = IP Header + TCP Header + TCP Len,其中TCP Header包含固定部分以及Options部分,固定部分为20字节,Options部分为20字节,IP Header部分为20字节,加在一起,可以得出TCP Len = 0。

32号包的seq=1,算是坐实了SYN这个标志值1 byte。

client端SYN标志占据1 byte,同样的,server端的SYN标志也占用1 byte。

何以见得?还是看32号包:

32号包的ACK=1!

关于这一点,Stevens在《TCP/IP Illustrated,Volume 1》是这么说的:

The sequence number of the first byte of data sent on this direction of the connection is the ISN plus 1 because the SYN bit field consumes one sequence number. As we shall see later, consuming a sequence number also implies reliable delivery using retransmission. Thus, SYNs and application bytes (and FINs, which we will see later) are reliably delivered. ACKs, which do not consume sequence numbers, are not.

让我们直接来看真实的网络包吧~

Data Transmission

正常通信的过程,那就是对端的Ack=发送端的Seq+Len

这是一次简单的HTTP GET 请求。

我们看33号包,client发出GET 请求,其seq=1,载荷TCP Len=106,它下一次数据包的seq应该就是从seq+tcp len = 107开始。

何以见得?请看34号包,server表示收到了client,也就是33号包发过来的请求,它进行了确认ack=107。正如开头所说,这就是TCP可靠性的真谛。

紧接着,36号包,client再次发送了数据包,它的seq果真就是107。bingo。

TCP Keep-alive

发送端seq龟缩大法

仔细观察,TCP保活机制中的包会有一种seq回退现象。

  • 25 号包

seq=1539,nextSeq=1578,说明它下一个包的seq应该从1578开始发起。

但它并没有!

  • 27 号包 - keep-alive

它的seq居然是从1577开始,比1578少了一个byte,这是为什么?

向后看,原来27号包是TCP Keep-Alive包,seq会发生回退。

  • 28号包 - keep-alive ack

作为27号包的响应包,它的ack=1578。如果后面是正常的数据传输,发送端的seq确实应该seq=1578开始传输。但如果发送端依然是保活包,也就是keep-alive的话,seq依然会从1578-1=1577开始。你不信的话,就看29号包!

Application Keep-alive

本质上就是应用层进行了数据传输。

上述网络包表示应用层自己实现的保活机制。保活包中的请求和响应都分别携带1 byte的数据,这一点可以从图中的TCP Payload Length看出。

所以相比TCP自身的保活机制,这里没什么稀奇古怪的。

拿250号包来说,seq=6190,len=1,那么确认250号包的ack应该为seq+len=6191。

查看251号包中的ack字段,发现的确如此!

这对于TCP来说,其实就是普普通通的数据传输过程。

Summary

让我们总结一下:

  • 三次握手、四次挥手:ack = seq+1(1指的是SYN、FIN标志,表示它们很重要)
  • 数据传输:ack = seq + len
  • TCP心跳保活:keep-alive包的seq会发生回退减1的情况,keep-alive-ack的ack是正常的。
  • 应用层的心跳保活:ack = seq + len,只不过是一种特殊的数据传输过程而已啦

Reference

  • 极客时间《网络排查案例课》
  • 林沛满《Wireshark网络分析的艺术》
  • Richard Stevens《TCP/IP Illustrated, Volume 1》
相关推荐
洋不写bug10 小时前
HTTP(二):万字解析HTTP交互的请求、响应报文格式
网络协议·http·交互·postman·请求格式·响应格式·restful规范
sun00770010 小时前
ip rule路由
网络·网络协议·tcp/ip
liuhaoodng62610 小时前
《网络IA项目:单臂路由(vlan间通讯)优化实战版》
运维·网络·网络协议
ITxiaobing202311 小时前
海外广告投放:AdTech 场景下 IP 地址库选型思考
服务器·网络·tcp/ip
洋不写bug12 小时前
HTTP(一):Fiddler下载、抓包请求响应解析
网络协议·http·fiddler·网络通信·抓包·http请求和响应
隐擎fox12 小时前
解密 HTTP/2 帧时序与流控指纹:Akamai H2 指纹逆向检测与协议重塑工程实战
网络·网络协议·tcp/ip·http
艾莉丝努力练剑12 小时前
【AI大模型接入SDK】Trae生成main方法
网络·人工智能·网络协议·http·架构·1024程序员节
青瓦梦滋1 天前
WebSocket协议
linux·服务器·网络·c++·websocket·网络协议·http
IpdataCloud1 天前
批量查IP的API接口怎么选?免费API配额瓶颈与离线库本地批量方案实测
网络·网络协议·tcp/ip
达~熊迪1 天前
IP 分配前核查:把在线状态和使用登记一起看
服务器·网络·tcp/ip