C#Winform获取实体网卡(非虚拟网卡),并判断有连接的网卡

最近在做一个项目的时候,需要给上传文件的进度条添加一个上传速度实时显示,通过网上资料查询,并总结一下,特地将相关代码分享出来给大家。

1.获取网卡,并获取该网卡当前的实时网速:

新建一个NetworkAdapter类

using System.Diagnostics;

namespace WaitDIalog
{
    class NetworkAdapter
    {
        /// <summary>
        /// Instances of this class are supposed to be created only in an NetworkMonitor.
        /// </summary>
        internal NetworkAdapter(string name)
        {
            this.name = name;
        }

        private long dlSpeed, ulSpeed;		 // Download/Upload speed in bytes per second.
        private long dlValue, ulValue;		 // Download/Upload counter value in bytes.
        private long dlValueOld, ulValueOld; // Download/Upload counter value one second earlier, in bytes.

        internal string name;								// The name of the adapter.
        internal PerformanceCounter dlCounter, ulCounter;	// Performance counters to monitor download and upload speed.
        /// <summary>
        /// Preparations for monitoring.
        /// </summary>
        internal void init()
        {
            // Since dlValueOld and ulValueOld are used in method refresh() to calculate network speed, they must have be initialized.
            this.dlValueOld = this.dlCounter.NextSample().RawValue;
            this.ulValueOld = this.ulCounter.NextSample().RawValue;
        }
        /// <summary>
        /// Obtain new sample from performance counters, and refresh the values saved in dlSpeed, ulSpeed, etc.
        /// This method is supposed to be called only in NetworkMonitor, one time every second.
        /// </summary>
        internal void refresh()
        {
            this.dlValue = this.dlCounter.NextSample().RawValue;
            this.ulValue = this.ulCounter.NextSample().RawValue;

            // Calculates download and upload speed.
            this.dlSpeed = this.dlValue - this.dlValueOld;
            this.ulSpeed = this.ulValue - this.ulValueOld;

            this.dlValueOld = this.dlValue;
            this.ulValueOld = this.ulValue;
        }
        /// <summary>
        /// Overrides method to return the name of the adapter.
        /// </summary>
        /// <returns>The name of the adapter.</returns>
        public override string ToString()
        {
            return this.name;
        }
        /// <summary>
        /// The name of the network adapter.
        /// </summary>
        public string Name
        {
            get { return this.name; }
        }
        /// <summary>
        /// Current download speed in bytes per second.
        /// </summary>
        public long DownloadSpeed
        {
            get { return this.dlSpeed; }
        }
        /// <summary>
        /// Current upload speed in bytes per second.
        /// </summary>
        public long UploadSpeed
        {
            get { return this.ulSpeed; }
        }
        /// <summary>
        /// Current download speed in kbytes per second.
        /// </summary>
        public double DownloadSpeedKbps
        {
            get { return this.dlSpeed / 1024.0; }
        }
        /// <summary>
        /// Current upload speed in kbytes per second.
        /// </summary>
        public double UploadSpeedKbps
        {
            get { return this.ulSpeed / 1024.0; }
        }
    }
}

新增一个NetworkMonitor类

using System.Collections;
using System.Diagnostics;
using System.Timers;

namespace WaitDIalog
{
    class NetworkMonitor
    {
        private Timer timer;				// The timer event executes every second to refresh the values in adapters.
        private ArrayList adapters;			// The list of adapters on the computer.
        private ArrayList monitoredAdapters;// The list of currently monitored adapters.

        public NetworkMonitor()
        {
            this.adapters = new ArrayList();
            this.monitoredAdapters = new ArrayList();
            EnumerateNetworkAdapters();

            timer = new Timer(2000);
            timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
        }
        /// <summary>
        /// Enumerates network adapters installed on the computer.
        /// </summary>
        private void EnumerateNetworkAdapters()
        {
            PerformanceCounterCategory category = new PerformanceCounterCategory("Network Interface");

            foreach (string name in category.GetInstanceNames())
            {
                // This one exists on every computer.
                if (name == "MS TCP Loopback interface")
                    continue;
                // Create an instance of NetworkAdapter class, and create performance counters for it.
                NetworkAdapter adapter = new NetworkAdapter(name);
                adapter.dlCounter = new PerformanceCounter("Network Interface", "Bytes Received/sec", name);
                adapter.ulCounter = new PerformanceCounter("Network Interface", "Bytes Sent/sec", name);
                this.adapters.Add(adapter);	// Add it to ArrayList adapter
            }
        }

        private void timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            foreach (NetworkAdapter adapter in this.monitoredAdapters)
                adapter.refresh();
        }
        /// <summary>
        /// Get instances of NetworkAdapter for installed adapters on this computer.
        /// </summary>
        public NetworkAdapter[] Adapters
        {
            get { return (NetworkAdapter[])this.adapters.ToArray(typeof(NetworkAdapter)); }
        }
        /// <summary>
        /// Enable the timer and add all adapters to the monitoredAdapters list, 
        /// unless the adapters list is empty.
        /// </summary>
        public void StartMonitoring()
        {
            if (this.adapters.Count > 0)
            {
                foreach (NetworkAdapter adapter in this.adapters)
                    if (!this.monitoredAdapters.Contains(adapter))
                    {
                        this.monitoredAdapters.Add(adapter);
                        adapter.init();
                    }

                timer.Enabled = true;
            }
        }
        /// <summary>
        /// Enable the timer, and add the specified adapter to the monitoredAdapters list
        /// </summary>
        public void StartMonitoring(NetworkAdapter adapter)
        {
            if (!this.monitoredAdapters.Contains(adapter))
            {
                this.monitoredAdapters.Add(adapter);
                adapter.init();
            }
            timer.Enabled = true;
        }
        /// <summary>
        /// Disable the timer, and clear the monitoredAdapters list.
        /// </summary>
        public void StopMonitoring()
        {
            this.monitoredAdapters.Clear();
            timer.Enabled = false;
        }
        /// <summary>
        /// Remove the specified adapter from the monitoredAdapters list, and 
        /// disable the timer if the monitoredAdapters list is empty.
        /// </summary>
        public void StopMonitoring(NetworkAdapter adapter)
        {
            if (this.monitoredAdapters.Contains(adapter))
                this.monitoredAdapters.Remove(adapter);
            if (this.monitoredAdapters.Count == 0)
                timer.Enabled = false;
        }
    }
}

主函数中实例化两个类的对象:

  private NetworkAdapter[] adapters;
  private NetworkMonitor monitor=new NetworkMonitor();

由此便可获取到计算机的实体网卡:

this.adapters = monitor.Adapters;

如下图所示,获取到本机有两个实体网卡
获取到的实体网卡
而实际上,在我们计算机的网络连接中看,有多个网络连接,包括什么虚拟网卡之类的,用上面的方法,便可轻松的获取到实体网卡。
计算机中的所有网络连接
网卡是获取好了,通过设置一个定时器Timer,便可以通过NetworkAdapter类的几个属性获取当前的网速(这里指的网速实际上是固定时间内流量,网速都是这么测出来的)。
添加定时器Timer,并设定刷新时间,并于事件绑定起来:

 this.timer1.Interval = 500;
 this.timer1.Tick += new System.EventHandler(this.TimerCounter_Tick);
 timer1.Start();
 private void TimerCounter_Tick(object sender, System.EventArgs e)
        {
            if (timeSecond == 1)
            {
                monitor.StopMonitoring();
                monitor.StartMonitoring(adapters[index]);
                NetworkAdapter adapter = this.adapters[index];
                this.labelControl_Upload.Text = String.Format("{0:n} kbps", adapter.UploadSpeedKbps);
                timeSecond = 2;
            }
            else
            {
                NetworkAdapter adapter = this.adapters[index];
                this.labelControl_Upload.Text = String.Format("{0:n} kbps", adapter.DownloadSpeedKbps);
            }
        }

这里虽然可以测出网速,但是难以从Load事件里直接确定具体使用的是哪一个网卡,因为在规定的刷新时间内,有可能刚好流量统计为0,所以这里不好确定。
此地采用一个自带的 NetworkInterface类来确定多个网卡,具体是哪一个网卡联网了。

2.确定有网络连接的网卡

NetworkInterface[] fNetworkInterfaces = NetworkInterface.GetAllNetworkInterfaces();

这里通过fNetworkInterfaces下的OperationalStatus属性来确定是否有网络连接,up为有网络连接,down为无网络连接。

#region 程序集 System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.dll
#endregion

namespace System.Net.NetworkInformation
{
    //
    // 摘要:
    //     指定网络接口的操作状态。
    public enum OperationalStatus
    {
        //
        // 摘要:
        //     网络接口已运行,可以传输数据包。
        Up = 1,
        //
        // 摘要:
        //     网络接口无法传输数据包。
        Down = 2,
        //
        // 摘要:
        //     网络接口正在运行测试。
        Testing = 3,
        //
        // 摘要:
        //     网络接口的状态未知。
        Unknown = 4,
        //
        // 摘要:
        //     网络接口不处于传输数据包的状态;它正等待外部事件。
        Dormant = 5,
        //
        // 摘要:
        //     由于缺少组件(通常为硬件组件),网络接口无法传输数据包。
        NotPresent = 6,
        //
        // 摘要:
        //     网络接口无法传输数据包,因为它运行在一个或多个其他接口之上,而这些“低层”接口中至少有一个已关闭。
        LowerLayerDown = 7
    }
}

这里通过几个简单的循环,即可确定出有网络连接的网卡:

foreach (var network in fNetworkInterfaces)
 {
  if (network.OperationalStatus == OperationalStatus.Up)
    {
      apa.Add(network.Description);
    }
 }
foreach (var net in apa)
 {
   for (int i = 0; i < adapters.Length; i++)
    {
       if (adapters[i].Name == net.ToString())
           {
             index = i;
           }
     }
 }

效果图:
实现效果图

3.总结

本文主要讲述了如何获取计算机的实体网卡(有线网卡、无线网卡),并确定具体哪一个网卡具有网络连接。

4.参考资料

https://blog.csdn.net/lisenyang/article/details/40107397参考一
https://www.cnblogs.com/tmdsleep/p/5727973.html参考二

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值