使用 Pcap.net 获取样本周期内流量最大的网络接口

Posted

技术标签:

【中文标题】使用 Pcap.net 获取样本周期内流量最大的网络接口【英文标题】:Get the network interface with the most traffic within a sample period using Pcap.net 【发布时间】:2019-02-18 19:39:26 【问题描述】:

我正在尝试使用 Pcap.net 包来分析在一个小样本周期(例如 10 秒)内跨多个网络接口的每秒流量(以比特为单位)。然后我想从结果中计算每秒总字节数的平均值,然后通过突出显示关联的 listBox 项来指示哪个接口的流量最大。

我正在使用包 github 中的这个示例:Statistics Example

我需要同时为每个接口执行此操作,因此我启动了一个方法,该方法最终在每个接口的单独线程中调用 PacketSampleStatistics 类。

我的问题是,一旦我在使用PacketSampleStatistics 类的方法中,我就不再知道如何通过索引来识别接口,因此我无法将它绑定到列表框项。

我填充列表框并为每个界面启动一个新线程,如下所示:

public Form1()

    InitializeComponent();
    // Retrieve the device list from the local machine

    IList<LivePacketDevice> allDevices = LivePacketDevice.AllLocalMachine;

    if (allDevices.Count == 0)
    
        Console.WriteLine("No interfaces found! Make sure WinPcap is installed.");
        return;
    

    // Print the list
    for (int i = 0; i != allDevices.Count; ++i)
    
        LivePacketDevice device = allDevices[i];
        Console.Write((i + 1) + ". " + device.Name);
        int pcapInt = i + 1;
        if (device.Description != null)
        
            Console.WriteLine(" (" + device.Description + ")");
            listBox1.Items.Add((pcapInt) + ". " + device.Description);
        
        else
            Console.WriteLine(" (No description available)");
    


    foreach (var netInts in listBox1.Items)
    
        int curIndex = 1 + listBox1.Items.IndexOf(netInts);
        Console.WriteLine(curIndex);
        Thread getStats = new Thread(() => GetNetStatistics(curIndex));
        Console.WriteLine("Interface index: " + curIndex);
        getStats.Start();
    

这会为每个网络接口创建一个新线程,并通过启动一个名为GetNetStatistics 的方法将每秒位数写入控制台。然后此方法启动StatisticsHandler,它使用PacketSampleStatistics 类在其自己的线程中将每个接口的每秒位数写入控制台,该线程正在工作。

我尝试调用一个委托来更新我的主窗体上的对象,如果我一次只为一个网络接口/一个线程执行此操作,这将起作用。但我需要能够同时为每个网络接口执行此操作。

我在PacketSampleStatistics 类末尾注释掉的代码表明我试图解决这个问题。

private void StatisticsHandler(PacketSampleStatistics statistics)


    // Current sample time
    DateTime currentTimestamp = statistics.Timestamp;

    // Previous sample time
    DateTime previousTimestamp = _lastTimestamp;

    // Set _lastTimestamp for the next iteration
    _lastTimestamp = currentTimestamp;

    // If there wasn't a previous sample than skip this iteration (it's the first iteration)
    if (previousTimestamp == DateTime.MinValue)
        return;

    // Calculate the delay from the last sample
    double delayInSeconds = (currentTimestamp - previousTimestamp).TotalSeconds;

    // Calculate bits per second
    double bitsPerSecond = Math.Truncate(statistics.AcceptedBytes * 8 / delayInSeconds);

    // Calculate packets per second
    double packetsPerSecond = statistics.AcceptedPackets / delayInSeconds;

    // Print timestamp and samples
    Console.WriteLine(statistics.Timestamp + " BPS: " + bitsPerSecond + " PPS: " + packetsPerSecond);

    //invoke delegate to update main form
    //MethodInvoker inv = delegate
    //
        //bytesSecond.Text = bitsPerSecond.ToString();
        //listBox1.Items[0] = listBox1.Items[0] + bitsPerSecond.ToString();
    //;
    //this.Invoke(inv);


【问题讨论】:

【参考方案1】:

似乎处理PacketSampleStatistics 的方法应该是使用接口id 初始化的类的成员。

【讨论】:

以上是关于使用 Pcap.net 获取样本周期内流量最大的网络接口的主要内容,如果未能解决你的问题,请参考以下文章

网络最大流量与载量容量的关系

分布式组件-Sentinel-常见流量控制算法

SIP 会话跟踪

为啥使用 PCap.NET 发送的数据包没有填写 TCP 选项?

.net 数据包捕获:pcap.net 与 Sharppcap

如何将 Pcap.Net 数据包类对象导出到 .pcap 文件