优先选 sharppcap:轻量、跨平台、支持 .net core/5+,内置 pcapfilereaderdevice 和常见协议解析器;但需注意 pcap 格式验证、运行时标识符配置及 tcp 流手动重组。

直接读取 PCAP 文件在 C# 里不能靠 System.IO 原生类搞定,必须用封装了 libpcap/winpcap/dumpcap 逻辑的第三方库——否则你连文件头都解析不对,更别说还原 TCP 流或提取 HTTP 载荷。
用 Pcap.Net 还是 SharpPcap?
Pcap.Net 依赖较重(需安装 WinPcap/Npcap),API 设计偏底层但控制力强;SharpPcap 更轻量、跨平台支持好(.NET Core/.NET 5+ 可用),且对常见协议(ARP、IP、TCP、UDP、DNS)有开箱即用的解析器。
- 如果你只做离线分析(不抓包、只读 PCAP),优先选
SharpPcap:它自带PcapFileReaderDevice,一行代码就能打开文件 - 若需兼容老系统(如 Windows 7 + .NET Framework 4.5),
Pcap.Net的 NuGet 包仍可工作,但要注意其PcapFileOpen不支持 PCAP-NG 格式 -
SharpPcap默认跳过损坏帧(比如截断的 TCP 包),想保留所有原始字节得手动设ignoreInvalidPackets = false
SharpPcap.PcapFileReaderDevice 读取时常见崩溃点
直接 new 一个 PcapFileReaderDevice 后调 Open(),大概率遇到 System.DllNotFoundException 或 ArgumentException: Invalid file header。
- 确保 PCAP 文件是标准格式:用
tshark -r in.pcap -c 1先验证能否被命令行工具识别;Wireshark 导出时勾选 “Standard PCAP (libpcap)” 而非 “PCAP-NG” - .NET 6+ 项目需在
.csproj中显式指定运行时标识符,否则 Linux/macOS 下可能找不到原生依赖:<runtimeidentifier>linux-x64</runtimeidentifier> - 别在
using块外访问PcapPacket的Packet.Ethernet.IpV4.Tcp层级属性——某一层不存在时会抛NullReferenceException,先用packet.Packet.Ethernet?.IpV4?.Tcp != null判空
从 PcapPacket 提取有效载荷的坑
很多人以为 packet.Data 就是应用层数据,其实它是从链路层开始的完整字节流,HTTP 请求头混在 TCP payload 里,还可能被分段、加密或压缩。
- 真正能当“原始 HTTP 内容”用的,是
tcp.PayloadData(tcp是packet.Packet.Ethernet.IpV4.Tcp),但它只返回当前帧的 TCP 载荷片段,不是完整会话 - 要拼 TCP 流,得自己维护连接五元组(srcIP, dstIP, srcPort, dstPort, protocol)状态,按序列号排序重组——
SharpPcap不提供自动流重组,别指望TcpStream类 - HTTPS 流量即使拿到 TCP payload,也是 TLS 记录层数据,
payload.Length > 5 && payload[0] == 0x17才表示可能是 TLS 应用数据,解密需要私钥,纯离线解析做不到
PCAP 解析真正的复杂点不在读文件,而在理解每一层封装边界和状态依赖。比如 IP 分片、TCP 乱序、TLS 握手包缺失——这些都会让“看似完整”的包解析出错。别急着写业务逻辑,先用 tshark -r file.pcap -V 对照看协议树,确认你代码里取的字段,在实际包里是否真的存在、是否被截断、是否属于同一会话。










