直接读取 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对照看协议树,确认你代码里取的字段,在实际包里是否真的存在、是否被截断、是否属于同一会话。
