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