代码之家  ›  专栏  ›  技术社区  ›  Pareidolia

序列号和确认号不匹配

  •  0
  • Pareidolia  · 技术社区  · 6 年前

    我最近一直在学习wireshark。在检查TCP段时,我看到了一种奇怪的情况,至少对我来说是这样。序列号和确认号不匹配。然后我意识到两个ACK之间的差异等于1.5个包的大小。然而,据我所知,ACK只会随着整个数据包的大小而增长。那么这里发生了什么?

    SEQ        ACK
    1          1
    2897       8689
    5793       13033 <--
    8689       14481
    11585
    14481
    

    Image of the trace

    2 回复  |  直到 6 年前
        1
  •  2
  •   Christopher Maynard    6 年前

    好的,这里没有什么可供参考的,但我猜您正在发送大数据包的机器上捕获数据包,即具有2896字节TCP负载的数据包。因此,您可以看到数据包 之前 它们是IP碎片,实际上是通过有线传输的。

    但你不能只在网络上发送2896字节的数据;以太网链路通常会施加1500字节的MTU(最大传输单元),当您考虑IP和TCP标头开销时,通常会得到1460字节的可用负载或MSS(最大段大小)。在您的情况下,看起来只有1448字节的可用MSS,很可能是由于添加了一个或多个IP和/或TCP头选项。

    在任何情况下,2896字节的有效负载将通过2个IP片段进行分段,每个IP片段包含1448字节的TCP有效负载。我很确定,您看到的是在从下一段接收到1个完整段加上1个IP段后,接收器发出的ACK。

    之前的ACK编号为8689,8689+2896=11585。现在,添加数据段的1/2(2896/2=1448),得到11585+1448=13033。这就是你看到的ACK号码。现在加上另外的1/2,得到13033+1448=14481,这是下一个数据包的ACK号。

    我希望这有意义?

    要深入了解本地数据包捕获的缺点,请访问Jasper Bongertz写得很好的博客, "The drawbacks of local packet captures"

        2
  •  1
  •   David Hellmanns    6 年前

    因为我没有名誉来评论克里斯托弗·梅纳德的回答,所以我在这里发表评论。

    正如Christopher正确指出的,MTU(最大传输单元)是标准以太网,网络为1500字节。然而,由于必须单独处理每个数据段,因此手工制作1460Bytes(1500Bytes-20Bytes IP头-20Bytes TCP头,忽略可能的TCP选项)TCP数据段会给网络堆栈带来很大的负载。

    例如,如果我想传输1Mb(等于1024*1024字节=1048576字节)的数据,它将导致1Mb/1460Bytes=719段。相比之下,1Mb/65525字节(理论上最大TCP段大小)=16段。由于内核中的开销主要与段/数据包大小无关,因此小段需要更多的处理。

    为了抵消这一事实,开发了TCP分段卸载(TSO)。TSO允许内核创建最大大小的TCP段,NIC(网络接口卡)使用硬件加速将这些段拆分为1460字节的独立TCP段。因此,不需要IP碎片。