TCP 中 SEQ 和 ACK 不匹配

Mismatch between SEQ and ACK in TCP

我一直在试图找出一个 HTTP 客户端和 HTTP 服务器之间的 TCP 连接保持在 ESTABLISHED 状态,挥之不去的情况。 1000 多个连接中的 1 或 2 个连接会发生这种情况。不清楚这里是不是client/server的问题

我写了一个 python 脚本(使用 scapy)来捕获所有 TCP 数据包以找出根本原因,我遇到了这个特定情况,其中 TCP SEQ 和 ACK 似乎不匹配并且它让我很困惑。

这是日志中有趣的部分,来自 scapy 脚本: (在同一端口 53332 上有大量数据包之后)

2019-12-21 15:54:43 10.0.1.2:8080 -> 10.0.1.3:53332 [ A] seq:769374665 ack:844297577 len:0
2019-12-21 15:54:43 10.0.1.2:8080 -> 10.0.1.3:53332 [PA] seq:769374665 ack:844297577 len:90
HTTP/1.1 200 OK
content-type: application/json; charset=UTF-8
content-length: 389255
2019-12-21 15:54:43 10.0.1.2:8080 -> 10.0.1.3:53332 [ A] seq:769374755 ack:844297577 len:8949
2019-12-21 15:54:43 10.0.1.2:8080 -> 10.0.1.3:53332 [PA] seq:769383704 ack:844297577 len:8949
2019-12-21 15:54:43 10.0.1.2:8080 -> 10.0.1.3:53332 [ A] seq:769392653 ack:844297577 len:8949
2019-12-21 15:54:43 10.0.1.3:53332 -> 10.0.1.2:8080 [ A] seq:844297577 ack:769383704 len:0
2019-12-21 15:54:43 10.0.1.2:8080 -> 10.0.1.3:53332 [PA] seq:769401602 ack:844297577 len:8949
2019-12-21 15:54:43 10.0.1.2:8080 -> 10.0.1.3:53332 [ A] seq:769410551 ack:844297577 len:8949
2019-12-21 15:54:43 10.0.1.2:8080 -> 10.0.1.3:53332 [PA] seq:769419500 ack:844297577 len:8949
2019-12-21 15:54:43 10.0.1.3:53332 -> 10.0.1.2:8080 [ A] seq:844297577 ack:769401602 len:0
2019-12-21 15:54:43 10.0.1.2:8080 -> 10.0.1.3:53332 [ A] seq:769428449 ack:844297577 len:8949
2019-12-21 15:54:43 10.0.1.2:8080 -> 10.0.1.3:53332 [PA] seq:769437398 ack:844297577 len:8949
2019-12-21 15:54:43 10.0.1.2:8080 -> 10.0.1.3:53332 [ A] seq:769446347 ack:844297577 len:8949
2019-12-21 15:54:43 10.0.1.2:8080 -> 10.0.1.3:53332 [PA] seq:769455296 ack:844297577 len:8949
2019-12-21 15:54:43 10.0.1.2:8080 -> 10.0.1.3:53332 [ A] seq:769464245 ack:844297577 len:8949
2019-12-21 15:54:43 10.0.1.2:8080 -> 10.0.1.3:53332 [PA] seq:769473194 ack:844297577 len:8949
2019-12-21 15:54:43 10.0.1.3:53332 -> 10.0.1.2:8080 [ A] seq:844297577 ack:769446347 len:0
2019-12-21 15:54:43 10.0.1.2:8080 -> 10.0.1.3:53332 [ A] seq:769482143 ack:844297577 len:8949
2019-12-21 15:54:43 10.0.1.2:8080 -> 10.0.1.3:53332 [PA] seq:769491092 ack:844297577 len:8949

...scapy 脚本一定在这里遗漏了几个数据包...

2019-12-21 15:54:43 10.0.1.3:53332 -> 10.0.1.2:8080 [ A] seq:844297577 ack:769750613 len:0
2019-12-21 15:54:43 10.0.1.3:53332 -> 10.0.1.2:8080 [ A] seq:844297577 ack:769764010 len:0

几个小时后:

2019-12-21 17:54:45 10.0.1.2:8080 -> 10.0.1.3:53332 [ A] seq:769764009 ack:844297577 len:0
2019-12-21 17:54:45 10.0.1.3:53332 -> 10.0.1.2:8080 [ A] seq:844297577 ack:769764010 len:0

在15:54:43,客户端回复了769764010的ACK,表示已经收到了769764010的数据。2小时后,服务器发送769764009的SEQ,比ACK少1。而client一直在继续发送769764010的ACK。

我很困惑,SEQ怎么会小于ACK(或者ACK怎么会大于SEQ)。我已经验证在两个系统上,连接仍处于 ESTABLISHED 状态,因此都没有发送 FIN,导致序列编号增加。

我错过了什么?

这实际上是@user207421的回答,但是用户选择评论,所以我写这个回答。

本来就没有问题。它是 TCP Keepalive 数据包,所有 TCP Keep-alive 数据包只是一个 ACK​​,其序列号设置为比连接的当前序列号小一。

因此确实没有不匹配。