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

如何通过Python或Wireshark API从pcap文件导出DICOM对象?

从网络数据包提取DICOM文件:Python与Wireshark API实现方案

当然可以!不管是借助Wireshark自带的工具/API,还是用纯Python脚本,都能实现从网络数据包里提取DICOM文件的需求,下面给你详细拆解两种可行方案:

方案一:用Wireshark官方工具/API实现

Wireshark本身提供了命令行工具和脚本API,能直接复用它成熟的DICOM解析逻辑,和GUI里的"导出对象=>DICOM"功能效果一致。

1. 用tshark命令行快速导出(最便捷)

tshark是Wireshark的命令行版本,相当于Wireshark的命令行API,一行命令就能完成导出:

tshark -r 你的数据包文件.pcapng --export-objects dicom,./dicom_output

参数解释:

  • -r:指定要解析的数据包文件
  • --export-objects:后面跟上协议类型(dicom)和输出目录,工具会自动识别包里的DICOM对象并导出到目标文件夹。

2. 用Lua脚本自定义提取(灵活扩展)

如果需要更定制化的逻辑(比如只提取特定设备发送的DICOM文件),可以用Wireshark的Lua脚本API编写插件:

-- 创建DICOM协议监听器
local dicom_tap = Listener.new("dicom")

-- 处理每个DICOM数据包
function dicom_tap.packet(pinfo, tvb)
    -- 获取DICOM对象的原始数据
    local dicom_raw = tvb:raw()
    -- 生成唯一文件名(用数据包编号区分)
    local filename = string.format("dicom_pkt_%d.dcm", pinfo.number)
    -- 写入文件
    local file = io.open(filename, "wb")
    if file then
        file:write(dicom_raw)
        file:close()
        print(string.format("已导出DICOM文件:%s", filename))
    end
end

把这个脚本保存为extract_dicom.lua,然后在Wireshark中通过工具→Lua控制台加载,或者放到Wireshark的插件目录重启软件,就能自动捕获并提取DICOM文件了。

方案二:用Python实现(脱离Wireshark GUI)

如果想在Python项目中集成提取逻辑,有两种常用方式:借助Wireshark解析引擎的pyshark,或者纯Python解析的scapy。

1. 用pyshark调用Wireshark解析引擎

pyshark封装了Wireshark的底层解析库,能直接复用它的DICOM协议解析能力,无需自己处理TCP分片等问题:
首先安装依赖:

pip install pyshark

然后编写提取脚本:

import pyshark
import os

# 配置输出目录和输入数据包文件
output_dir = "./extracted_dicom"
pcap_file = "你的数据包文件.pcapng"

os.makedirs(output_dir, exist_ok=True)

# 加载数据包并过滤DICOM流量
cap = pyshark.FileCapture(pcap_file, display_filter="dicom")

for idx, pkt in enumerate(cap, start=1):
    # 检查数据包是否包含DICOM数据
    if hasattr(pkt, "dicom"):
        # 获取DICOM原始二进制数据
        dicom_raw = pkt.dicom.get_raw_value()
        # 保存为.dcm文件
        save_path = os.path.join(output_dir, f"dicom_{idx}.dcm")
        with open(save_path, "wb") as f:
            f.write(dicom_raw)
        print(f"已保存:{save_path}")

cap.close()

2. 用scapy纯Python解析(无Wireshark依赖)

如果需要完全脱离Wireshark环境,可以用scapy手动解析TCP流并提取DICOM文件(需要自己处理TCP分片重组):
首先安装依赖:

pip install scapy

然后编写脚本:

from scapy.all import rdpcap, TCP, Raw, IP
import os

output_dir = "./scapy_extracted_dicom"
pcap_file = "你的数据包文件.pcapng"

os.makedirs(output_dir, exist_ok=True)

# 读取数据包并重组TCP流
tcp_streams = {}
for pkt in rdpcap(pcap_file):
    if IP in pkt and TCP in pkt and Raw in pkt:
        # 用(源IP, 源端口, 目标IP, 目标端口)作为流的唯一标识
        stream_key = (pkt[IP].src, pkt[TCP].sport, pkt[IP].dst, pkt[TCP].dport)
        if stream_key not in tcp_streams:
            tcp_streams[stream_key] = b""
        # 累加TCP载荷数据
        tcp_streams[stream_key] += pkt[Raw].load

# 遍历每个TCP流,查找并提取DICOM文件
stream_idx = 0
for stream_data in tcp_streams.values():
    # DICOM文件的特征:前128字节为预留字段,第129-132字节是"DICM"标记
    dicm_marker_pos = stream_data.find(b"DICM")
    if dicm_marker_pos != -1 and dicm_marker_pos >= 128:
        # 提取完整的DICOM文件(从预留字段开始到流结束)
        dicom_file_data = stream_data[dicom_marker_pos - 128:]
        stream_idx += 1
        save_path = os.path.join(output_dir, f"dicom_stream_{stream_idx}.dcm")
        with open(save_path, "wb") as f:
            f.write(dicom_file_data)
        print(f"已提取DICOM文件:{save_path}")

方案选择建议

  • 如果只是快速导出DICOM文件,tshark命令行是最省心的选择;
  • 如果需要在Wireshark中自定义提取逻辑,Lua脚本更灵活;
  • 如果要集成到Python项目中,pyshark能复用Wireshark的成熟解析,适合大多数场景;
  • 如果需要完全脱离Wireshark环境,scapy是纯Python的解决方案,但需要自己处理更多底层细节。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 07:02:44