最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于C#和ScottPlot開發(fā)專業(yè)級(jí)網(wǎng)絡(luò)流量監(jiān)控工具

 更新時(shí)間:2025年08月15日 10:20:28   作者:小碼編匠  
這篇文章主要為大家詳細(xì)介紹了如何使用 C# 和強(qiáng)大的 ScottPlot 可視化庫,從零開始構(gòu)建一個(gè)專業(yè)級(jí)的網(wǎng)絡(luò)流量監(jiān)控工具,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

前言

軟件開發(fā)和系統(tǒng)運(yùn)維中,網(wǎng)絡(luò)性能是決定應(yīng)用穩(wěn)定性和用戶體驗(yàn)的關(guān)鍵因素。

大家是否曾遇到過這樣的情況:正在處理重要任務(wù)時(shí),網(wǎng)絡(luò)突然變得異常緩慢,卻無法確定是哪個(gè)程序在"偷跑"流量?或者作為運(yùn)維人員,需要實(shí)時(shí)掌握服務(wù)器的網(wǎng)絡(luò)負(fù)載情況,但市面上的工具要么功能臃腫,要么界面陳舊難用。

本文將帶你使用 C# 和強(qiáng)大的 ScottPlot 可視化庫,從零開始構(gòu)建一個(gè)專業(yè)級(jí)的網(wǎng)絡(luò)流量監(jiān)控工具。它不僅具備實(shí)時(shí)監(jiān)控、動(dòng)態(tài)圖表、多網(wǎng)卡支持等核心功能,還擁有美觀的界面和高度可定制性。更重要的是,整個(gè)過程將幫助大家深入理解網(wǎng)絡(luò)編程、數(shù)據(jù)可視化與性能優(yōu)化的核心技術(shù)。

項(xiàng)目功能

這款網(wǎng)絡(luò)流量監(jiān)控工具在解決實(shí)際問題,具備以下核心功能:

  • 實(shí)時(shí)監(jiān)控上傳與下載速度,精確到每秒。
  • 通過動(dòng)態(tài)折線圖展示歷史流量數(shù)據(jù),直觀呈現(xiàn)網(wǎng)絡(luò)波動(dòng)。
  • 支持選擇多個(gè)網(wǎng)絡(luò)接口,方便在多網(wǎng)卡環(huán)境下進(jìn)行監(jiān)控。
  • 展示詳細(xì)的網(wǎng)絡(luò)統(tǒng)計(jì)信息,如總收發(fā)字節(jié)數(shù)。
  • 提供啟動(dòng)/停止監(jiān)控的控制按鈕,操作靈活。

核心技術(shù)

項(xiàng)目基于 .NET Framework 和 WinForm 開發(fā),結(jié)合 ScottPlot 這一強(qiáng)大的開源繪圖庫,實(shí)現(xiàn)高效的數(shù)據(jù)可視化。

必備 NuGet 包:

<PackageReference Include="ScottPlot.WinForms" Version="5.0.0" />

關(guān)鍵命名空間:

using ScottPlot;                        // 圖表核心功能
using ScottPlot.WinForms;              // WinForms集成
using System.Net.NetworkInformation;   // 網(wǎng)絡(luò)接口操作
using Timer = System.Windows.Forms.Timer; // 定時(shí)器

核心架構(gòu)

首先定義工具所需的數(shù)據(jù)結(jié)構(gòu)和變量:

public partial class Form1 : Form
{ 
    // 定時(shí)器和網(wǎng)絡(luò)接口
    private Timer updateTimer;
    private NetworkInterface selectedInterface;
    private List<NetworkInterface> networkInterfaces;
    
    // 歷史數(shù)據(jù)存儲(chǔ)
    private List<double> downloadHistory;
    private List<double> uploadHistory;
    private List<DateTime> timeHistory;
    
    // 基準(zhǔn)數(shù)據(jù)用于計(jì)算差值
    private long lastBytesReceived;
    private long lastBytesSent;
    private DateTime lastUpdateTime;
    
    // 數(shù)據(jù)點(diǎn)控制
    private int maxHistoryPoints = 60; // 保留60個(gè)數(shù)據(jù)點(diǎn)(1分鐘歷史)
    
    // ScottPlot 圖表對(duì)象
    private ScottPlot.Plottables.Scatter downloadPlot;
    private ScottPlot.Plottables.Scatter uploadPlot;
}

設(shè)計(jì)亮點(diǎn)

采用"差值計(jì)算法"來精確測(cè)量網(wǎng)絡(luò)速度。通過記錄上一次的接收和發(fā)送字節(jié)數(shù),結(jié)合時(shí)間間隔,計(jì)算出實(shí)時(shí)速率,避免了累積誤差。

核心功能實(shí)現(xiàn)

網(wǎng)絡(luò)接口發(fā)現(xiàn)與初始化:

private void LoadNetworkInterfaces()
{ 
    // 獲取所有活躍的非回環(huán)網(wǎng)絡(luò)接口
    networkInterfaces = NetworkInterface.GetAllNetworkInterfaces()
        .Where(ni => ni.OperationalStatus == OperationalStatus.Up &&
                     ni.NetworkInterfaceType != NetworkInterfaceType.Loopback)
        .ToList();
    
    comboBoxInterfaces.Items.Clear();
    foreach (var ni in networkInterfaces)
    { 
        // 顯示友好的接口名稱
        comboBoxInterfaces.Items.Add($"{ni.Name} ({ni.NetworkInterfaceType})");
    }
    
    if (comboBoxInterfaces.Items.Count > 0)
    { 
        comboBoxInterfaces.SelectedIndex = 0;
        selectedInterface = networkInterfaces[0];
        
        // ?? 關(guān)鍵:初始化基準(zhǔn)值,確保第一次計(jì)算的準(zhǔn)確性
        var stats = selectedInterface.GetIPv4Statistics();
        lastBytesReceived = stats.BytesReceived;
        lastBytesSent = stats.BytesSent;
    }
}

注意事項(xiàng)

  • 過濾掉回環(huán)接口(Loopback)以避免干擾。
  • 僅選擇處于“運(yùn)行中”(Up)狀態(tài)的接口。
  • 初始化基準(zhǔn)值是確保首次計(jì)算準(zhǔn)確的關(guān)鍵步驟。

圖表初始化與配置

private void SetupChart()
{ 
    // 清除所有繪圖對(duì)象
    formsPlot.Plot.Clear();
    formsPlot.Plot.Legend.FontName = "SimSun"; // 中文字體支持
    
    // ?? 坐標(biāo)軸美化
    formsPlot.Plot.Axes.Left.Label.Text = "速度 (KB/s)";
    formsPlot.Plot.Axes.Bottom.Label.Text = "時(shí)間";
    formsPlot.Plot.Axes.Left.Label.FontSize = 12;
    formsPlot.Plot.Axes.Bottom.Label.FontSize = 12;
    formsPlot.Plot.Axes.Bottom.Label.FontName = "SimSun";
    formsPlot.Plot.Axes.Left.Label.FontName = "SimSun";
    
    // ?? 創(chuàng)建下載速度線條
    downloadPlot = formsPlot.Plot.Add.Scatter(new double[0], new double[0]);
    downloadPlot.Color = ScottPlot.Color.FromHtml("#007BFF"); // 專業(yè)藍(lán)色
    downloadPlot.LineWidth = 2;
    downloadPlot.MarkerSize = 0; // 不顯示數(shù)據(jù)點(diǎn),保持線條流暢
    downloadPlot.LegendText = "下載速度";
    
    // ?? 創(chuàng)建上傳速度線條
    uploadPlot = formsPlot.Plot.Add.Scatter(new double[0], new double[0]);
    uploadPlot.Color = ScottPlot.Color.FromHtml("#DC3545"); // 警示紅色
    uploadPlot.LineWidth = 2;
    uploadPlot.MarkerSize = 0;
    uploadPlot.LegendText = "上傳速度";
    
    // 顯示圖例并設(shè)置時(shí)間軸
    formsPlot.Plot.ShowLegend(Alignment.UpperRight);
    formsPlot.Plot.Axes.DateTimeTicksBottom(); // 時(shí)間軸格式化
    formsPlot.Refresh();
}

設(shè)計(jì)技巧

  • 使用專業(yè)配色方案提升視覺效果。
  • 時(shí)間軸自動(dòng)格式化,提升用戶體驗(yàn)。
  • 圖例置于右上角,避免遮擋主要數(shù)據(jù)。

實(shí)時(shí)數(shù)據(jù)更新核心邏輯:

private void UpdateTimer_Tick(object sender, EventArgs e)
{ 
    if (selectedInterface == null) return;
    
    try
    { 
        var stats = selectedInterface.GetIPv4Statistics();
        var currentTime = DateTime.Now;
        var timeSpan = (currentTime - lastUpdateTime).TotalSeconds;
        
        // ?? 核心算法:差值法計(jì)算實(shí)時(shí)速度
        if (timeSpan > 0 && lastBytesReceived > 0 && lastBytesSent > 0)
        { 
            // 計(jì)算速度 (KB/s)
            double downloadSpeed = (stats.BytesReceived - lastBytesReceived) / timeSpan / 1024;
            double uploadSpeed = (stats.BytesSent - lastBytesSent) / timeSpan / 1024;
            
            // ??? 防御性編程:確保速度不為負(fù)數(shù)
            downloadSpeed = Math.Max(0, downloadSpeed);
            uploadSpeed = Math.Max(0, uploadSpeed);
            
            // 更新各個(gè)顯示組件
            UpdateRealTimeDisplay(downloadSpeed, uploadSpeed, stats);
            UpdateHistory(downloadSpeed, uploadSpeed, currentTime);
            UpdateChart();
        }
        
        // 更新基準(zhǔn)值
        lastBytesReceived = stats.BytesReceived;
        lastBytesSent = stats.BytesSent;
        lastUpdateTime = currentTime;
    }
    catch (Exception ex)
    { 
        // ?? 優(yōu)雅的錯(cuò)誤處理
        labelStatus.Text = $"監(jiān)控錯(cuò)誤: {ex.Message}";
        labelStatus.ForeColor = System.Drawing.Color.Red;
    }
}

算法亮點(diǎn)

  • 通過差值除以時(shí)間間隔得到精確的實(shí)時(shí)速度。
  • 防御性編程確保速度值非負(fù)。
  • 異常處理機(jī)制保證程序整體穩(wěn)定性。

動(dòng)態(tài)圖表更新:

private void UpdateChart()
{ 
    if (timeHistory.Count == 0) return;
    
    try
    { 
        // ?? 時(shí)間格式轉(zhuǎn)換:DateTime轉(zhuǎn)OADate用于ScottPlot
        double[] timeArray = timeHistory.Select(t => t.ToOADate()).ToArray();
        double[] downloadArray = downloadHistory.ToArray();
        double[] uploadArray = uploadHistory.ToArray();
        
        // ?? 動(dòng)態(tài)更新策略:移除舊對(duì)象,添加新對(duì)象
        if (downloadPlot != null)
            formsPlot.Plot.Remove(downloadPlot);
        if (uploadPlot != null)
            formsPlot.Plot.Remove(uploadPlot);
        
        // 重新創(chuàng)建圖表對(duì)象
        downloadPlot = formsPlot.Plot.Add.Scatter(timeArray, downloadArray);
        downloadPlot.Color = ScottPlot.Color.FromHtml("#007BFF");
        downloadPlot.LineWidth = 2;
        downloadPlot.MarkerSize = 0;
        downloadPlot.LegendText = "下載速度";
        
        uploadPlot = formsPlot.Plot.Add.Scatter(timeArray, uploadArray);
        uploadPlot.Color = ScottPlot.Color.FromHtml("#DC3545");
        uploadPlot.LineWidth = 2;
        uploadPlot.MarkerSize = 0;
        uploadPlot.LegendText = "上傳速度";
        
        formsPlot.Plot.ShowLegend(Alignment.UpperRight);
        
        // ?? 智能坐標(biāo)軸調(diào)整
        formsPlot.Plot.Axes.AutoScale();
        
        // 設(shè)置X軸顯示最近的時(shí)間窗口
        if (timeArray.Length > 0)
        { 
            var latestTime = timeArray[timeArray.Length - 1];
            var earliestTime = DateTime.Now.AddSeconds(-maxHistoryPoints).ToOADate();
            formsPlot.Plot.Axes.SetLimitsX(earliestTime, latestTime);
        }
        
        formsPlot.Refresh();
    }
    catch (Exception ex)
    { 
        // ??? 圖表更新失敗不影響主程序
        System.Diagnostics.Debug.WriteLine($"Chart update error: {ex.Message}");
    }
}

用戶界面交互:

private void comboBoxInterfaces_SelectedIndexChanged(object sender, EventArgs e)
{ 
    if (comboBoxInterfaces.SelectedIndex >= 0)
    { 
        selectedInterface = networkInterfaces[comboBoxInterfaces.SelectedIndex];
        
        // ?? 重置統(tǒng)計(jì)基準(zhǔn)
        var stats = selectedInterface.GetIPv4Statistics();
        lastBytesReceived = stats.BytesReceived;
        lastBytesSent = stats.BytesSent;
        lastUpdateTime = DateTime.Now;
        
        // 清空歷史數(shù)據(jù)重新開始
        downloadHistory.Clear();
        uploadHistory.Clear();
        timeHistory.Clear();
        
        // 重新初始化圖表
        formsPlot.Plot.Clear();
        SetupChart();
        
        labelStatus.Text = $"已切換到: {selectedInterface.Name}";
        labelStatus.ForeColor = System.Drawing.Color.Blue;
    }
}

private void buttonStartStop_Click(object sender, EventArgs e)
{ 
    if (updateTimer.Enabled)
    { 
        // ?? 停止監(jiān)控
        updateTimer.Stop();
        buttonStartStop.Text = "開始監(jiān)控";
        buttonStartStop.BackColor = System.Drawing.Color.FromArgb(40, 167, 69);
        labelStatus.Text = "監(jiān)控已停止";
        labelStatus.ForeColor = System.Drawing.Color.Red;
    }
    else
    { 
        // ?? 開始監(jiān)控
        updateTimer.Start();
        buttonStartStop.Text = "停止監(jiān)控";
        buttonStartStop.BackColor = System.Drawing.Color.FromArgb(220, 53, 69);
        labelStatus.Text = "監(jiān)控已開始";
        labelStatus.ForeColor = System.Drawing.Color.Green;
    }
}

高級(jí)優(yōu)化技巧

數(shù)據(jù)格式化工具:

private string FormatSpeed(double bytesPerSecond)
{ 
    // ?? 智能單位轉(zhuǎn)換
    if (bytesPerSecond < 1024)
        return $"{bytesPerSecond:F1} B/s";
    else if (bytesPerSecond < 1024 * 1024)
        return $"{bytesPerSecond / 1024:F1} KB/s";
    else if (bytesPerSecond < 1024L * 1024 * 1024)
        return $"{bytesPerSecond / (1024 * 1024):F1} MB/s";
    else
        return $"{bytesPerSecond / (1024L * 1024 * 1024):F1} GB/s";
}

private string FormatBytes(long bytes)
{ 
    // ?? 流量統(tǒng)計(jì)格式化
    if (bytes < 1024)
        return $"{bytes} B";
    else if (bytes < 1024 * 1024)
        return $"{bytes / 1024.0:F1} KB";
    else if (bytes < 1024L * 1024 * 1024)
        return $"{bytes / (1024.0 * 1024):F1} MB";
    else if (bytes < 1024L * 1024 * 1024 * 1024)
        return $"{bytes / (1024.0 * 1024 * 1024):F1} GB";
    else
        return $"{bytes / (1024.0 * 1024 * 1024 * 1024):F1} TB";
}

內(nèi)存管理與資源清理

private void UpdateHistory(double downloadSpeed, double uploadSpeed, DateTime currentTime)
{ 
    downloadHistory.Add(downloadSpeed);
    uploadHistory.Add(uploadSpeed);
    timeHistory.Add(currentTime);
    
    // ?? 滑動(dòng)窗口:自動(dòng)清理過期數(shù)據(jù)
    while (downloadHistory.Count > maxHistoryPoints)
    { 
        downloadHistory.RemoveAt(0);
        uploadHistory.RemoveAt(0);
        timeHistory.RemoveAt(0);
    }
}

protected override void OnFormClosing(FormClosingEventArgs e)
{ 
    // ?? 優(yōu)雅關(guān)閉:清理資源
    updateTimer?.Stop();
    updateTimer?.Dispose();
    base.OnFormClosing(e);
}

實(shí)戰(zhàn)應(yīng)用場(chǎng)景

企業(yè)級(jí)應(yīng)用

  • 服務(wù)器監(jiān)控:部署在生產(chǎn)服務(wù)器上,實(shí)時(shí)監(jiān)控帶寬使用情況。
  • 網(wǎng)絡(luò)診斷:快速定位網(wǎng)絡(luò)性能瓶頸,排查異常流量。
  • 流量統(tǒng)計(jì):為網(wǎng)絡(luò)容量規(guī)劃和成本控制提供數(shù)據(jù)支持。

開發(fā)調(diào)試

  • API 測(cè)試:監(jiān)控接口調(diào)用過程中的網(wǎng)絡(luò)開銷,評(píng)估性能。
  • 性能優(yōu)化:識(shí)別應(yīng)用中網(wǎng)絡(luò)密集型的操作,進(jìn)行針對(duì)性優(yōu)化。
  • 資源監(jiān)控:實(shí)時(shí)追蹤特定應(yīng)用或進(jìn)程的網(wǎng)絡(luò)資源消耗。

技術(shù)要點(diǎn)

性能優(yōu)化秘籍

1、異步 UI 更新:使用 Invoke 確保圖表更新在主線程執(zhí)行,保證線程安全。

2、數(shù)據(jù)點(diǎn)控制:限制歷史數(shù)據(jù)數(shù)量,避免內(nèi)存泄漏。

3、異常隔離:將圖表更新等非核心功能的異常進(jìn)行捕獲,不影響數(shù)據(jù)采集主流程。

常見坑點(diǎn)規(guī)避

  • 初始化陷阱:必須在開始監(jiān)控前設(shè)置正確的基準(zhǔn)字節(jié)數(shù)。
  • 負(fù)數(shù)速度:網(wǎng)絡(luò)接口重置可能導(dǎo)致字節(jié)數(shù)歸零,需使用 Math.Max 防止速度為負(fù)。
  • 線程安全:所有 UI 操作必須在主線程中執(zhí)行。

項(xiàng)目源碼

Gitee:gitee.com/smallcore/DotNetCore/tree/master/DotNetCore/NetworkTool

總結(jié)

通過這個(gè)項(xiàng)目,我們不僅成功開發(fā)了一個(gè)功能完備、界面美觀的網(wǎng)絡(luò)流量監(jiān)控工具,更重要的是深入掌握了多項(xiàng)核心技術(shù):從 NetworkInterface 類的高級(jí)用法,到 ScottPlot 的數(shù)據(jù)可視化最佳實(shí)踐,再到性能優(yōu)化與異常處理的工程思維。這個(gè)工具可以直接應(yīng)用于實(shí)際工作場(chǎng)景,不管是系統(tǒng)運(yùn)維還是應(yīng)用開發(fā),都能提供有力的支持。

更重要的是,它展示了如何將簡(jiǎn)單的技術(shù)組件組合起來,解決復(fù)雜的實(shí)際問題,這正是編程的魅力所在。

到此這篇關(guān)于基于C#和ScottPlot開發(fā)專業(yè)級(jí)網(wǎng)絡(luò)流量監(jiān)控工具的文章就介紹到這了,更多相關(guān)C# ScottPlot網(wǎng)絡(luò)流量監(jiān)控內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

丁青县| 西华县| 永康市| 湄潭县| 黎城县| 芒康县| 吉林省| 凤台县| 宁城县| 长乐市| 永康市| 叶城县| 桃园市| 全椒县| 宁城县| 安康市| 青阳县| 禹城市| 吉林省| 临沂市| 巩义市| 大埔区| 荥经县| 喀喇沁旗| 成武县| 板桥市| 崇信县| 滕州市| 和政县| 鹿泉市| 永济市| 赤峰市| 剑阁县| 永善县| 林州市| 永昌县| 江都市| 翁牛特旗| 贵州省| 广东省| 光泽县|