我的应用程序(客户端)连接到一个事务处理服务器(TP 服务器)。我们看到一个奇怪的数据包序列,其中 TP 服务器发送一个带有空 (0) 字节数据的 PUSH 数据包,但该数据包的序列号不正确;该序列号是最后收到的字节的序列号。
请查看此处的 TCP 转储数据
http://pastebin.com/5UBXWazy
172.250.10.10.13824 是 TP 服务器。
172.11.105.5.49524 是客户端。
“TP-Server”不在我的控制范围内,不确定它在什么操作系统上运行。“Client”是我在 Debian Squeeze 上运行的支付应用程序。
您可以看到下面的数据包中TP-Server发送了一个空字节数据。
20:52:34.472819 IP (tos 0x0, ttl 59, id 51820, offset 0, flags [DF], proto TCP (6), length 53)
172.250.10.10.13824 > 172.11.105.5.49524: Flags [P.], cksum 0xe36f (correct), seq 1457045850:1457045851, ack 3097912286, win 17680, options [nop,nop,TS val 646012206 ecr 73190886], length 1
0x0000: 4500 0035 ca6c 4000 3b06 a941 acfa 0a0a E..5.l@.;..A....
0x0010: ac0b 6905 3600 c174 56d8 c15a b8a6 63de ..i.6..tV..Z..c.
0x0020: 8018 4510 e36f 0000 0101 080a 2681 5d2e ..E..o......&.].
0x0030: 045c cde6 00 .\...
上述空字节数据的序列号标记为 1457045850。但如下所示,该数据是在更早的时间接收的。
20:50:22.506267 IP (tos 0x0, ttl 59, id 51817, offset 0, flags [DF], proto TCP (6), length 607)
172.250.10.10.13824 > 172.11.105.5.49524: Flags [P.], cksum 0x6460 (correct), seq 1457045296:1457045851, ack 3097912253, win 17680, options [nop,nop,TS val 645999009 ecr 73187775], length 555
对于不正确的序列号,客户端会用一个 sack 标志来响应,表明不正确的序列号。
20:52:34.472864 IP (tos 0x0, ttl 64, id 1172, offset 0, flags [DF], proto TCP (6), length 64)
172.11.105.5.49524 > 172.250.10.10.13824: Flags [.], cksum 0x4501 (correct), seq 3097912286, ack 1457045851, win 2003, options [nop,nop,TS val 73220891 ecr 646012206,nop,nop,sack 1 {1457045850:1457045851}], length 0
TP-Server又重复发送了7次相同的空字节数据,并且序列号也都是错误的。Client也努力用sack回应。
20:58:29.024492 IP (tos 0x0, ttl 59, id 51827, offset 0, flags [DF], proto TCP (6), length 53)
172.250.10.10.13824 > 172.11.105.5.49524: Flags [P.], cksum 0x04bf (correct), seq 1457045850:1457045851, ack 3097912308, win 17680, options [nop,nop,TS val 646047661 ecr 73277952], length 1
0x0000: 4500 0035 ca73 4000 3b06 a93a acfa 0a0a E..5.s@.;..:....
0x0010: ac0b 6905 3600 c174 56d8 c15a b8a6 63f4 ..i.6..tV..Z..c.
0x0020: 8018 4510 04bf 0000 0101 080a 2681 e7ad ..E.........&...
0x0030: 045e 2200 00 .^"..
20:58:29.024553 IP (tos 0x0, ttl 64, id 1179, offset 0, flags [DF], proto TCP (6), length 64)
172.11.105.5.49524 > 172.250.10.10.13824: Flags [.], cksum 0x602c (correct), seq 3097912308, ack 1457045851, win 2003, options [nop,nop,TS val 73309529 ecr 646047661,nop,nop,sack 1 {1457045850:1457045851}], length 0
但是,当第 8 次发生同样的情况时,客户端停止提供确认。TP 服务器继续发送空字节数据 5 次,但客户端均未提供确认。此行为发生在网络堆栈级别,我可怜的客户端应用程序没有收到任何套接字错误,仅在时间“21:18:59”时,它收到了 getsocketopt err:110(我认为是 ETIMED_OUT)。因此,我的客户端应用程序等待了一段时间,并尝试在 21:21:38 重新连接(您可以看到 SYN 数据包)。但是,此后 TP 服务器没有响应。几分钟后重新启动“客户端”PC 后,TP 服务器接受了新连接。但是,相同的空字节数据包又开始重新出现。有时,会发生这样的情况,客户端有一些定期数据包需要以大约 10 秒的间隔发送到 TP 服务器,并且这保持连接处于活动状态,而不管是否仍出现空字节以及客户端是否使用 sack 进行响应。
我的问题:
发送这些带有错误序列号的空数据字节的原因是什么?
我应该对 debian 网络堆栈采取任何措施来处理这种情况以保持连接处于活动状态吗?