与声称问题原因的供应商有关的问题在tcp数据中是无效的“ack”值。 我正在使用java,所以我没有写这个图层。 我使用snoop来捕获线路上的stream量,并使用wireshark来显示数据。 这是发生了什么事。 收到多包(5)消息后,我看到一个多包(3)响应。 响应中的第一个数据包的“ack”值与其他两个数据包中的“ack”值不同。 供应商声称这个数据是可疑的。 我在下面提供了示例数据。 我不是一个TCP专家,所以我不知道这是否是一个问题。 我试图find有效的ack值的东西,在我看来,价值应该是80018,但这并不意味着78345是错误的。 我在网上发现了这一点,似乎也适用,但我不确定:“只要数据段在下一个段发送之前不确认数据,就认为任何数据段的ack值都是有效的”。 谢谢你的帮助。 我的理解是供应商已经编写了自己的tcp层。
源seq ack len时间
我10734 75465 190 yyyymmdd 09:18:21.785757
供应商75465 10924 0 yyyymmdd 09:18:21.789319
供应商75465 10924 1440 yyyymmdd 09:18:34.196661
供应商76905 10924 1440 yyyymmdd 09:18:34.196762
供应商78345 10924 1440 yyyymmdd 09:18:34.196901
供应商79785 10924 233 yyyymmdd 09:18:34.196915
我10924 78345 0 yyyymmdd 09:18:34.196968
我10924 80018 0 yyyymmdd 09:18:34.197102
我10924 80018 197 yyyymmdd 09:18:34.579479
http://en.wikipedia.org/wiki/Transmission_Control_Protocol说
确认号码(32位) – 如果设置了ACK标志,那么这个字段的值就是接收器期望的下一个序列号。 这确认收到所有以前的字节(如果有的话)。 每一端发送的第一个ACK确认对方本身的初始序列号,但是没有数据。
这表明第一个回复数据包正在确认收到来自供应商的前三个数据包(seq 76905 + len 1440 = 78345)
第二个回复数据包确认收到来自供应商的第四个和第五个数据包(seq 79785 + len 233 = 80018)
第三个回复数据包表示没有收到来自供应商的进一步数据(相同的ack)并且包含197个字节的有效载荷。
这对我来说看起来不错。
如果你的数据是整个对话,那么最初的ack会是错误的,因为它应该从75465(seq 75465 + 1 = 75466)确认第一个数据包。
这里是我用wireshark捕获的一个序列,首先我们看到三次握手,然后传输一个HTTP请求,然后是一个HTTP响应
Source Flags Seq Ack Len 客户端SYN 0 - 0 服务器SYN,ACK 0 1 0 客户端ACK 1 1 0 客户 - 1 1 429获取... 服务器ACK 1 430 0 服务器 - 1 430 1456 HTML响应 服务器 - 1457 430 1456 客户端ACK 430 2913 0 ...
序号和确认号码是相对的(对每一端的随机select的起始号码)
对一系列请求使用单个连接是常见的优化。 它被添加到版本为1.1的HTTP,并被称为持续连接 。 build立和拆除TCP连接是有代价的。
简而言之,ACK字段用于指示接收方期望从发送方接收的下一个序列号。 也就是说,最后收到的段的序列号+该段的长度。 (还有其他一些用于处理丢失/重传的用途,但我们暂时将这些用处留出)。
TCP被devise成可以在单个响应中确认多个分段。 这可以更高效地利用高延迟链接。 请参阅RFC1122和RFC2581 ,特别是关于延迟确认的部分。
就你的具体问题而言:一个TCP协议栈总会有一定程度的交错; 也就是说,即使最后一个数据包(seq 79785)已经放入接收缓冲区,它也可能没有在允许的时间内被处理,然后ACK必须被发回到连接的另一端。 你提供的标题似乎描绘了一个完全正常的TCP对话给我。 你的供应商的解释似乎充其量是可疑的。