C#如何获取指定网络适配器的发送/接收字节数统计数据
C# 获取Hyper-V桥接环境下物理网络适配器统计数据方案
适用环境
- 支持 .NET Framework 4.8 / .NET 5+
- 仅兼容Windows操作系统(依赖Win32 IP Helper原生API)
实现原理
Windows IP Helper API提供的GetIfEntry2函数可直接通过物理适配器的接口索引获取底层统计数据,不受Hyper-V虚拟桥接、网卡共享等逻辑层配置影响,返回数据与控制面板网络状态页展示的统计值完全一致。
完整实现代码
using System; using System.Linq; using System.Net.NetworkInformation; using System.Runtime.InteropServices; public static class NetworkAdapterStatistics { // IP Helper API 结构体定义 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] private struct MIB_IF_ROW2 { public ulong InterfaceLuid; public uint InterfaceIndex; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string Alias; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string Description; public uint PhysicalAddressLength; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] PhysicalAddress; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] PermanentPhysicalAddress; public uint Mtu; public uint Type; public uint TunnelType; public uint MediaType; public uint PhysicalMediumType; public uint AccessType; public uint DirectionType; [MarshalAs(UnmanagedType.Bool)] public bool Multicast; public ulong TransmitLinkSpeed; public ulong ReceiveLinkSpeed; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public ulong[] InOctets; public ulong InUcastPkts; public ulong InNUcastPkts; public ulong InDiscards; public ulong InErrors; public ulong InUnknownProtos; public ulong InUcastOctets; public ulong InMulticastOctets; public ulong InBroadcastOctets; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public ulong[] OutOctets; public ulong OutUcastPkts; public ulong OutNUcastPkts; public ulong OutDiscards; public ulong OutErrors; public ulong OutUcastOctets; public ulong OutMulticastOctets; public ulong OutBroadcastOctets; public ulong OutQLen; } // P/Invoke 声明 [DllImport("iphlpapi.dll", SetLastError = true)] private static extern uint GetIfEntry2(ref MIB_IF_ROW2 pIfRow); /// <summary> /// 获取指定物理网络适配器的统计数据 /// </summary> /// <param name="adapterName">物理适配器名称(对应NetworkInterface.Name)</param> /// <returns>适配器统计数据,未找到对应适配器返回null</returns> public static AdapterStatistics GetPhysicalAdapterStatistics(string adapterName) { // 过滤出物理网卡,排除Hyper-V虚拟网卡、桥接逻辑网卡 var physicalAdapter = NetworkInterface.GetAllNetworkInterfaces() .FirstOrDefault(nic => nic.Name == adapterName && nic.NetworkInterfaceType != NetworkInterfaceType.Tunnel && nic.NetworkInterfaceType != NetworkInterfaceType.Loopback && !nic.Description.Contains("Hyper-V Virtual Ethernet Adapter") && !nic.Description.Contains("Microsoft Network Adapter Multiplexor")); if (physicalAdapter == null) return null; var ifRow = new MIB_IF_ROW2 { InterfaceIndex = (uint)physicalAdapter.GetIPProperties().GetIPv4Properties().Index }; var result = GetIfEntry2(ref ifRow); if (result != 0) return null; return new AdapterStatistics { ReceivedBytes = ifRow.InOctets[0], SentBytes = ifRow.OutOctets[0], ReceivedPackets = ifRow.InUcastPkts + ifRow.InNUcastPkts, SentPackets = ifRow.OutUcastPkts + ifRow.OutNUcastPkts, InboundErrors = ifRow.InErrors, OutboundErrors = ifRow.OutErrors, DiscardedPackets = ifRow.InDiscards + ifRow.OutDiscards }; } } /// <summary> /// 网络适配器统计数据模型 /// </summary> public class AdapterStatistics { public ulong ReceivedBytes { get; set; } public ulong SentBytes { get; set; } public ulong ReceivedPackets { get; set; } public ulong SentPackets { get; set; } public ulong InboundErrors { get; set; } public ulong OutboundErrors { get; set; } public ulong DiscardedPackets { get; set; } }
使用示例
// 示例:获取名为"以太网"的物理网卡统计数据 var stats = NetworkAdapterStatistics.GetPhysicalAdapterStatistics("以太网"); if (stats != null) { Console.WriteLine($"已接收字节:{stats.ReceivedBytes}"); Console.WriteLine($"已发送字节:{stats.SentBytes}"); }
注意事项
- 若需枚举所有可用物理网卡,可遍历
NetworkInterface.GetAllNetworkInterfaces()返回的集合,按上述代码中的过滤规则筛选即可 - 调用时需确保程序拥有管理员权限,部分受限环境下可能无法读取低层级网卡统计数据
内容的提问来源于stack exchange,提问作者p.g.
相关产品推荐
相关产品推荐

