Rust网络监控库netwatch的使用:高效网络流量分析与实时监控工具

Rust网络监控库netwatch的使用:高效网络流量分析与实时监控工具

netwatch 是一个跨平台的库,用于监控网络接口和路由变化。

该库由n0团队开发,并被用于iroh项目。

许可证

该项目采用以下任一许可证:

  • Apache License, Version 2.0
  • MIT license

安装

在项目目录中运行以下Cargo命令:

cargo add netwatch

或在Cargo.toml中添加:

netwatch = "0.8.0"

示例代码

以下是一个完整的netwatch使用示例,展示如何监控网络接口变化:

use netwatch::{InterfaceWatcher, Watcher};
use std::time::Duration;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 创建网络接口监视器
    let watcher = InterfaceWatcher::new()?;
    
    // 获取当前所有网络接口
    let interfaces = watcher.interfaces()?;
    println!("当前网络接口:");
    for iface in interfaces {
        println!(" - {}: {:?}", iface.name, iface.addresses);
    }

    // 设置变化回调
    watcher.watch(move |event| {
        println!("网络接口变化: {:?}", event);
    })?;

    // 持续运行监控
    loop {
        std::thread::sleep(Duration::from_secs(1));
    }
}

完整示例demo

基于上述示例,这是一个更完整的网络监控实现,增加了流量统计功能:

use netwatch::{InterfaceWatcher, Watcher};
use std::time::{Duration, Instant};

// 网络流量统计结构体
struct TrafficStats {
    bytes_sent: u64,
    bytes_received: u64,
    last_update: Instant,
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 创建网络接口监视器
    let watcher = InterfaceWatcher::new()?;
    
    // 初始化流量统计
    let mut stats = TrafficStats {
        bytes_sent: 0,
        bytes_received: 0,
        last_update: Instant::now(),
    };

    // 获取初始网络接口状态
    let interfaces = watcher.interfaces()?;
    println!("初始网络接口状态:");
    for iface in interfaces {
        println!("接口 {}: 发送={} 接收={}", 
            iface.name, 
            iface.tx_bytes.unwrap_or(0),
            iface.rx_bytes.unwrap_or(0)
        );
        stats.bytes_sent += iface.tx_bytes.unwrap_or(0);
        stats.bytes_received += iface.rx_bytes.unwrap_or(0);
    }

    // 设置变化回调
    watcher.watch(move |event| {
        match event {
            netwatch::Event::InterfaceAdded(iface) => {
                println!("新增接口: {}", iface.name);
            }
            netwatch::Event::InterfaceRemoved(name) => {
                println!("移除接口: {}", name);
            }
            netwatch::Event::InterfaceChanged(iface) => {
                // 更新流量统计
                stats.bytes_sent += iface.tx_bytes.unwrap_or(0);
                stats.bytes_received += iface.rx_bytes.unwrap_or(0);
                
                // 每秒打印一次统计信息
                if stats.last_update.elapsed() >= Duration::from_secs(1) {
                    println!(
                        "流量统计 - 发送: {}/s 接收: {}/s",
                        stats.bytes_sent,
                        stats.bytes_received
                    );
                    stats.bytes_sent = 0;
                    stats.bytes_received = 0;
                    stats.last_update = Instant::now();
                }
            }
        }
    })?;

    // 持续运行监控
    loop {
        std::thread::sleep(Duration::from_secs(1));
    }
}

文档

更多详细文档可参考官方文档。

贡献

除非您明确声明,否则您提交的任何贡献都将按照上述Apache-2.0许可证进行双重授权,无需任何额外的条款或条件。


1 回复

Rust网络监控库netwatch的使用:高效网络流量分析与实时监控工具

介绍

netwatch是一个高效的Rust网络监控库,专门设计用于网络流量分析和实时监控。它提供了低级别的网络数据包捕获能力,同时保持了Rust的安全性和性能优势。

主要特性:

  • 跨平台支持(Linux, macOS, Windows)
  • 高性能数据包捕获
  • 实时流量分析
  • 支持过滤特定协议或端口
  • 可扩展的监控架构

安装方法

在Cargo.toml中添加依赖:

[dependencies]
netwatch = "0.3"

基本使用方法

1. 简单网络监控示例

use netwatch::{NetworkInterface, MonitorBuilder};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 获取默认网络接口
    let interface = NetworkInterface::default()?;
    
    // 创建监控器
    let monitor = MonitorBuilder::new()
        .interface(interface)
        .promiscuous_mode(true)
        .build()?;
    
    // 开始捕获数据包
    for packet in monitor.capture_packets() {
        println!("捕获到数据包: {:?}", packet);
    }
    
    Ok(())
}

2. 过滤特定协议

use netwatch::{NetworkInterface, MonitorBuilder, Protocol};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let interface = NetworkInterface::default()?;
    
    let monitor = MonitorBuilder::new()
        .interface(interface)
        .filter(Protocol::TCP)  // 只监控TCP流量
        .build()?;
    
    for packet in monitor.capture_packets().take(10) {
        println!("TCP数据包: {:?}", packet);
    }
    
    Ok(())
}

3. 实时流量统计

use netwatch::{NetworkInterface, MonitorBuilder, StatsCollector};
use std::time::Duration;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let interface = NetworkInterface::default()?;
    
    let monitor = MonitorBuilder::new()
        .interface(interface)
        .build()?;
    
    let stats = StatsCollector::new(monitor);
    
    loop {
        std::thread::sleep(Duration::from_secs(5));
        let report = stats.report();
        println!("5秒内流量统计:");
        println!("总数据包: {}", report.total_packets);
        println!("总字节数: {}", report.total_bytes);
        println!("按协议分布: {:?}", report.protocol_distribution);
    }
}

高级用法

自定义数据包处理器

use netwatch::{NetworkInterface, MonitorBuilder, Packet, PacketHandler};

struct MyPacketHandler;

impl PacketHandler for MyPacketHandler {
    fn handle(&mut self, packet: Packet) {
        // 自定义处理逻辑
        println!("自定义处理: 源IP {} -> 目标IP {}", packet.source, packet.destination);
    }
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let interface = NetworkInterface::default()?;
    
    let handler = MyPacketHandler;
    
    let monitor = MonitorBuilder::new()
        .interface(interface)
        .packet_handler(handler)
        .build()?;
    
    monitor.start()?;
    
    Ok(())
}

监控特定端口

use netwatch::{NetworkInterface, MonitorBuilder};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let interface = NetworkInterface::default()?;
    
    let monitor = MonitorBuilder::new()
        .interface(interface)
        .port_filter(80)  // 只监控80端口(HTTP)
        .build()?;
    
    for packet in monitor.capture_packets() {
        println!("HTTP流量: {:?}", packet);
    }
    
    Ok(())
}

性能优化建议

  1. 对于高性能场景,使用zero-copy模式:
MonitorBuilder::new()
    .zero_copy(true)  // 启用零拷贝模式
    // ...其他配置
  1. 限制捕获的数据包大小以提高性能:
MonitorBuilder::new()
    .snaplen(96)  // 只捕获每个数据包的前96字节
    // ...其他配置
  1. 使用多线程处理:
use std::sync::mpsc;

let (tx, rx) = mpsc::channel();
let monitor = MonitorBuilder::new()
    .packet_sender(tx)
    .build()?;

std::thread::spawn(move || {
    for packet in rx {
        // 在单独线程中处理数据包
    }
});

完整示例demo

下面是一个结合了多种功能的完整示例,展示如何使用netwatch进行高级网络监控:

use netwatch::{
    NetworkInterface, 
    MonitorBuilder, 
    Protocol,
    Packet,
    PacketHandler,
    StatsCollector
};
use std::time::Duration;
use std::sync::mpsc;
use std::thread;

// 自定义数据包处理器
struct AdvancedHandler {
    tx: mpsc::Sender<String>,  // 用于发送统计信息的通道
}

impl PacketHandler for AdvancedHandler {
    fn handle(&mut self, packet: Packet) {
        // 处理TCP协议的HTTP流量
        if packet.protocol == Protocol::TCP && packet.destination_port == Some(80) {
            let info = format!(
                "HTTP请求: {} -> {} 大小: {}字节",
                packet.source,
                packet.destination,
                packet.size
            );
            self.tx.send(info).unwrap();
        }
    }
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 获取默认网络接口
    let interface = NetworkInterface::default()?;
    
    // 创建统计信息通道
    let (stats_tx, stats_rx) = mpsc::channel();
    
    // 创建监控器
    let monitor = MonitorBuilder::new()
        .interface(interface)
        .filter(Protocol::TCP)  // 只监控TCP流量
        .port_filter(80)        // 监控80端口
        .snaplen(256)           // 限制捕获大小
        .promiscuous_mode(true) // 启用混杂模式
        .packet_handler(AdvancedHandler { tx: stats_tx })
        .build()?;
    
    // 创建统计收集器
    let stats = StatsCollector::new(monitor.try_clone()?);
    
    // 启动统计线程
    thread::spawn(move || {
        for msg in stats_rx {
            println!("[流量分析] {}", msg);
        }
    });
    
    // 启动监控线程
    let monitor_handle = thread::spawn(move || {
        monitor.start().unwrap();
    });
    
    // 主线程显示统计信息
    loop {
        thread::sleep(Duration::from_secs(10));
        let report = stats.report();
        println!("\n=== 10秒流量报告 ===");
        println!("总数据包: {}", report.total_packets);
        println!("总字节数: {}", report.total_bytes);
        println!("协议分布: {:?}", report.protocol_distribution);
    }
    
    // 实际应用中需要处理线程join
    // monitor_handle.join().unwrap();
}

这个完整示例展示了:

  1. 使用自定义数据包处理器
  2. 多线程处理网络流量
  3. 实时统计和报告功能
  4. 特定协议和端口的过滤
  5. 性能优化配置

netwatch库为Rust开发者提供了强大而灵活的网络监控能力,结合Rust的性能优势,非常适合构建高性能的网络监控和分析工具。

回到顶部