什么是有效的“ack”值?

什么是有效的“ack”值?

遇到一个供应商的问题,该供应商声称问题的原因是 tcp 数据中的无效“ack”值。我使用的是 java,所以我没有编写这一层。我使用 snoop 捕获线路上的流量,并使用 wireshark 显示数据。这是正在发生的事情。收到多数据包(5)消息后,我看到了多数据包(3)响应。响应中的第一个数据包的“ack”值与其他两个数据包中的“ack”值不同。供应商声称这些数据是可疑的。我在下面提供了示例数据。我不是 tcp 专家,所以我不知道这是否是个问题。我试图找到一些关于有效 ack 值的东西,在我看来,这个值应该是 80018,但这并不意味着 78345 是错误的。我在网上找到了这个,它似乎适用,但我不确定:“任何数据段的 ack 值只要不在下一个要发送的段之前确认数据,就被视为有效”​​。谢谢你的帮助。我的理解是供应商已经编写了自己的 tcp 层。

    源序列确认长度时间
    我 10734 75465 190 年月日 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 年月日 09:18:34.196968
    我 10924 80018 0 年月日 09:18:34.197102
    我 10924 80018 197 年月日 09:18:34.579479

答案1

http://en.wikipedia.org/wiki/Transmission_Control_Protocol

确认号(32 位)——如果设置了 ACK 标志,则此字段的值是接收方期望的下一个序列号。这确认已收到所有先前的字节(如果有)。每一端发送的第一个 ACK​​ 确认另一端的初始序列号本身,但不确认数据。

这表明第一个回复数据包确认收到了来自小贩(序号 76905 + 长度 1440 = 78345)

第二个回复数据包确认收到来自小贩(序号 79785 + 长度 233 = 80018)

第三个回复数据包表示没有收到来自小贩(相同的确认)并包含 197 字节的有效载荷。

对我来说这看起来不错。

如果你的数据是整个对话,那么初始确认将是错误的,因为它应该确认来自小贩确认为 75465(序号 75465 + 1 = 75466)。

下面是我用 wireshark 捕获的序列,首先我们看到三次握手,然后是 HTTP get 请求的传输,接着是 HTTP 响应

源标志序列确认长度  
客户端 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  
客户端确认 430 2913 0  
...   

序列号和确认号是相对的(相对于每一端随机选择的起始号)


使用单个连接来处理一系列请求是一种常见的优化方法。它被添加到 HTTP 1.1 版本中,被称为持久连接. 建立和拆除 TCP 连接是有成本的。

答案2

简而言之,ACK 字段用于指示接收方期望从发送方收到的下一个序列号。即,最后收到的段的序列号 + 该段的长度。(还有一些与处理丢失/重传相关的其他用途,但我们现在先不讨论这些)。

TCP 的设计使得可以在单个响应中确认多个段。这样可以更有效地利用高延迟链路。请参阅RFC1122RFC2581,特别是有关延迟确认的部分。

就您的具体问题而言:TCP 堆栈始终会存在一定程度的交错;也就是说,即使最后一个数据包(序列号 79785)已放置在接收缓冲区中,在必须将 ACK 发送回连接的另一端之前,它也可能未在允许的时间内得到处理。您提供的标头在我看来似乎描述了一次完全正常的 TCP 对话。您的供应商的解释充其量也令人生疑。

相关内容