Crates.io | pcapfile-io |
lib.rs | pcapfile-io |
version | 0.1.2 |
created_at | 2025-08-21 08:39:18.664609+00 |
updated_at | 2025-09-17 10:08:13.341979+00 |
description | 高性能PCAP文件读写库 |
homepage | |
repository | https://github.com/Zoranner/pcapfile-io |
max_upload_size | |
id | 1804450 |
size | 282,779 |
一个用 Rust 编写的高性能数据包文件处理库,提供完整的数据包文件读写功能。本库使用自定义的 PCAP 格式,专为高性能数据采集和回放设计。
在 Cargo.toml
中添加依赖:
[dependencies]
pcapfile-io = "0.1.0"
chrono = "0.4" # 用于时间戳处理
use pcapfile_io::{PcapReader, PcapWriter, DataPacket};
use pcapfile_io::business::config::{ReaderConfig, WriterConfig};
use chrono::Utc;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 写入数据包
{
let config = WriterConfig::default();
let mut writer = PcapWriter::new("./data", "my_dataset", config)?;
// 创建数据包
let data = b"Hello, World!".to_vec();
let packet = DataPacket::from_datetime(Utc::now(), data)?;
writer.write_packet(&packet)?;
writer.flush()?;
} // writer 自动完成 finalize
// 读取数据包(默认带校验结果)
{
let config = ReaderConfig::default();
let mut reader = PcapReader::new("./data", "my_dataset", config)?;
while let Some(validated_packet) = reader.read_packet()? {
if validated_packet.is_valid() {
println!("读取到有效数据包: {} 字节", validated_packet.packet_length());
println!("时间戳: {}", validated_packet.capture_time());
} else {
println!("读取到损坏数据包: {} 字节 (继续处理)", validated_packet.packet_length());
}
}
}
Ok(())
}
use pcapfile_io::{PcapReader, DataPacket};
use pcapfile_io::business::config::ReaderConfig;
fn read_data_only() -> Result<(), Box<dyn std::error::Error>> {
let config = ReaderConfig::default();
let mut reader = PcapReader::new("./data", "my_dataset", config)?;
// 如果不关心校验结果,可以直接获取数据包
while let Some(packet) = reader.read_packet_data_only()? {
println!("读取到数据包: {} 字节", packet.packet_length());
// 注意:这种方式仍然进行校验,只是不返回校验结果
}
Ok(())
}
use pcapfile_io::{PcapWriter, DataPacket};
use pcapfile_io::business::config::WriterConfig;
use chrono::Utc;
fn batch_operations() -> Result<(), Box<dyn std::error::Error>> {
let config = WriterConfig::default();
let mut writer = PcapWriter::new("./data", "batch_dataset", config)?;
// 批量写入
let mut packets = Vec::new();
for i in 0..1000 {
let data = format!("数据包 #{}", i).into_bytes();
let packet = DataPacket::from_datetime(Utc::now(), data)?;
packets.push(packet);
}
writer.write_packets(&packets)?;
writer.flush()?;
Ok(())
}
DataPacket
- 数据包pub struct DataPacket {
pub header: DataPacketHeader,
pub data: Vec<u8>,
}
impl DataPacket {
// 创建方法
pub fn from_datetime(capture_time: DateTime<Utc>, data: Vec<u8>) -> Result<Self, String>;
pub fn from_timestamp(timestamp_seconds: u32, timestamp_nanoseconds: u32, data: Vec<u8>) -> Result<Self, String>;
// 访问方法
pub fn capture_time(&self) -> DateTime<Utc>;
pub fn packet_length(&self) -> usize;
pub fn checksum(&self) -> u32;
pub fn is_valid(&self) -> bool; // 内部校验
}
ValidatedPacket
- 带校验结果的数据包pub struct ValidatedPacket {
pub packet: DataPacket,
pub is_valid: bool, // 校验是否通过
}
impl ValidatedPacket {
pub fn is_valid(&self) -> bool;
pub fn is_invalid(&self) -> bool;
// 委托给内部数据包的方法
pub fn packet_length(&self) -> usize;
pub fn capture_time(&self) -> DateTime<Utc>;
pub fn get_timestamp_ns(&self) -> u64;
pub fn checksum(&self) -> u32;
}
PcapReader
- 数据集读取器pub struct PcapReader { /* ... */ }
impl PcapReader {
// 构造方法
pub fn new<P: AsRef<Path>>(base_path: P, dataset_name: &str, config: ReaderConfig) -> PcapResult<Self>;
// 默认读取方法(带校验结果)
pub fn read_packet(&mut self) -> PcapResult<Option<ValidatedPacket>>;
pub fn read_packets(&mut self, count: usize) -> PcapResult<Vec<ValidatedPacket>>;
// 仅数据读取方法(不返回校验信息)
pub fn read_packet_data_only(&mut self) -> PcapResult<Option<DataPacket>>;
pub fn read_packets_data_only(&mut self, count: usize) -> PcapResult<Vec<DataPacket>>;
// 控制方法
pub fn reset(&mut self) -> PcapResult<()>;
// 信息查询
pub fn get_dataset_info(&mut self) -> PcapResult<DatasetInfo>;
}
PcapWriter
- 数据集写入器pub struct PcapWriter { /* ... */ }
impl PcapWriter {
// 构造方法
pub fn new<P: AsRef<Path>>(base_path: P, dataset_name: &str, config: WriterConfig) -> PcapResult<Self>;
// 写入方法
pub fn write_packet(&mut self, packet: &DataPacket) -> PcapResult<()>;
pub fn write_packets(&mut self, packets: &[DataPacket]) -> PcapResult<()>;
// 控制方法
pub fn flush(&mut self) -> PcapResult<()>;
// finalize() 在 Drop 时自动调用
// 信息查询
pub fn get_dataset_info(&self) -> DatasetInfo;
}
ReaderConfig
- 读取器配置pub struct ReaderConfig {
pub common: CommonConfig,
pub read_timeout: u64, // 读取超时时间(毫秒)
}
impl ReaderConfig {
pub fn default() -> Self;
pub fn high_performance() -> Self; // 高性能配置
pub fn low_memory() -> Self; // 低内存配置
}
WriterConfig
- 写入器配置pub struct WriterConfig {
pub common: CommonConfig,
pub max_packets_per_file: usize, // 每个文件最大数据包数
pub file_name_format: String, // 文件命名格式
pub auto_flush: bool, // 自动刷新
pub write_timeout: u64, // 写入超时时间(毫秒)
pub index_flush_interval: u64, // 索引刷新间隔(毫秒)
}
impl WriterConfig {
pub fn default() -> Self;
pub fn high_performance() -> Self; // 高性能配置
pub fn low_memory() -> Self; // 低内存配置
pub fn fast_write() -> Self; // 快速写入配置
}
CommonConfig
- 通用配置pub struct CommonConfig {
pub buffer_size: usize, // 缓冲区大小(字节)
pub max_packet_size: usize, // 最大数据包大小(字节)
pub enable_compression: bool, // 是否启用压缩
pub index_cache_size: usize, // 索引缓存大小(条目数)
pub enable_index_cache: bool, // 是否启用文件索引缓存
pub temp_directory: PathBuf, // 临时目录路径
}
本库提供了灵活的数据校验和错误处理机制:
ValidatedPacket
类型获取校验结果// 处理可能损坏的数据集(默认方法)
let mut reader = PcapReader::new("./data", "dataset", config)?;
let mut valid_count = 0;
let mut invalid_count = 0;
while let Some(validated_packet) = reader.read_packet()? {
if validated_packet.is_valid() {
valid_count += 1;
// 处理有效数据包
process_packet(&validated_packet.packet);
} else {
invalid_count += 1;
// 记录损坏的数据包,但继续处理
log::warn!("发现损坏数据包,时间戳: {}", validated_packet.capture_time());
// 可选择是否仍然使用损坏的数据
if should_use_corrupted_data() {
process_packet(&validated_packet.packet);
}
}
}
println!("处理完成: {} 有效, {} 损坏", valid_count, invalid_count);
// 高性能配置示例
let high_perf_config = WriterConfig::high_performance();
// - 64KB 缓冲区
// - 每文件 2000 个数据包
// - 关闭自动刷新
// - 10秒索引刷新间隔
// 低内存配置示例
let low_mem_config = ReaderConfig::low_memory();
// - 4KB 缓冲区
// - 100 条目索引缓存
// - 关闭索引缓存
let mut reader = PcapReader::new("./data", "my_dataset", config)?;
let info = reader.get_dataset_info()?;
println!("数据集: {}", info.name);
println!("文件数: {}", info.file_count);
println!("总数据包数: {}", info.total_packets);
println!("总大小: {} 字节", info.total_size);
println!("时间范围: {:?}", info.time_range());
println!("平均速率: {:.2} 包/秒", info.average_packet_rate());
本库使用自定义的 PCAP 格式,针对高性能场景优化:
偏移量 | 长度 | 字段名 | 描述 |
---|---|---|---|
0 | 4 | Magic Number | 固定值 0xD4C3B2A1 |
4 | 2 | Major Version | 主版本号 0x0002 |
6 | 2 | Minor Version | 次版本号 0x0004 |
8 | 4 | Timezone Offset | 时区偏移量(秒) |
12 | 4 | Timestamp Accuracy | 时间戳精度(纳秒) |
每个数据包包含:
偏移量 | 长度 | 字段名 | 描述 |
---|---|---|---|
0 | 4 | Timestamp Seconds | 时间戳秒部分(UTC) |
4 | 4 | Timestamp Nanoseconds | 时间戳纳秒部分(UTC) |
8 | 4 | Packet Length | 数据包长度(字节) |
12 | 4 | Checksum | 数据包校验和(CRC32) |
dataset_name/
├── data_20231201_120000_123456789.pcap # 数据文件
├── data_20231201_120100_987654321.pcap # 数据文件
├── ...
└── dataset_name.pidx # 索引文件(自动生成)
运行所有测试:
cargo test
运行特定测试:
cargo test test_data_consistency
cargo test test_large_dataset
运行基准测试:
cargo bench
在典型硬件配置下的性能表现:
操作 | 吞吐量 | 延迟 |
---|---|---|
写入 1KB 数据包 | ~100MB/s | <1ms |
读取 1KB 数据包 | ~150MB/s | <0.5ms |
批量写入 (1000包) | ~200MB/s | ~10ms |
索引查询 | ~1M 查询/s | <1μs |
use pcapfile_io::foundation::error::{PcapError, PcapResult};
// 错误类型
pub enum PcapError {
FileNotFound(String),
DirectoryNotFound(String),
InsufficientPermissions(String),
InvalidFormat(String),
CorruptedData(String),
InvalidPacketSize(String),
Io(std::io::Error),
// ...
}
// 结果类型
pub type PcapResult<T> = Result<T, PcapError>;
查看 examples/
目录中的完整示例:
# 基本使用
cargo run --example dataset_usage
# 运行所有示例
find examples -name "*.rs" -exec cargo run --example {} \;
我们欢迎各种形式的贡献!
# 克隆项目
git clone https://github.com/username/pcapfile-io.git
cd pcapfile-io
# 安装依赖
cargo build
# 运行测试
cargo test
# 检查代码格式
cargo fmt --check
cargo clippy
本项目采用 MIT 许可证 - 查看 LICENSE 文件了解详情。
PcapFile.IO - 让数据包文件处理变得简单高效! 🚀