You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Scapy接收分片数据包时出现延迟的问题排查

Scapy抓包时TCP分片包延迟触发回调的问题分析

问题背景

使用Scapy 2.5.0 + Python 3.11.5抓取特定应用数据包,简化复现代码如下:

from scapy.all import *

def callback(packet):
    load: bytes = bytes(packet[TCP].payload)
    ip_layer = packet.getlayer(IP)
    ip_id = int(ip_layer.id)
    print(ip_id, len(load))

sniff(filter='ip and src host xx.xx.xx.xx',prn=callback)

异常现象

源端发送大体积数据时会拆分为多个分片包,第一个包能正常接收并打印,但第二个包需等到第三个包到达时才会被一同打印:

packet_1 received:
    load: b"a lot of data that needs to b"
    ip_id: 1
...
...
some time elapsed
...
...
packet_2 received:
    load: b"e split in several packets\x00"
    ip_id: 2
packet_3 received:
    load: b"data that has no connection with the two previous packets\x00"
    ip_id: 3

目标应用可正常接收并拼接分片数据(推测通过\x00结束符处理),但Scapy的回调触发存在明显延迟。

问题分析与解决

  • 与第一个包无\x00无关:Scapy的回调触发逻辑不依赖应用层的结束符,它仅负责捕获底层网络包并传递给回调函数。
  • 核心原因:Scapy默认TCP重组机制:Scapy默认启用TCP分片重组(conf.TCP_segment_reassemble默认值为True),收到第一个分片后会等待后续分片完成重组,才会将完整TCP流数据传递给回调。第二个分片虽携带\x00,但Scapy仍可能等待更多数据,直到第三个包(新TCP流)到来时,才触发之前缓存分片的处理。
  • 这是默认行为而非已知问题:TCP重组是Scapy为方便用户获取完整应用层数据设计的默认逻辑,并非bug。
  • 解决方法:
    • 在代码开头添加conf.TCP_segment_reassemble = False,关闭TCP重组功能。
    • 关闭后,每个TCP分片都会立即触发回调,可实时打印ip_id=1、2、3的数据包,不会出现延迟。

内容的提问来源于stack exchange,提问作者NicoTine

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 00:22:37