Introduction
The .NET Class Library provides a set of performance counters that you can use to track the performance both of the system and of an application. This program makes use of counters in the Networking category to obtain information about data sent and received over the network, and calculates network speed.
Using the code
This library includes only two classes, NetworkMonitor
and NetworkAdapter
. The former one provides general methods to enumerate network adapters installed on a computer, start or stop watching specified adapter, and a timer to read performance counter samples every second, and the latter represents a specific network adapter, providing properties presenting current speed.
The following code is a simple example of using these two classes:
NetworkMonitor monitor = new NetworkMonitor();
NetworkAdapter[] adapters = monitor.Adapters;
if (adapters.Length == 0)
{
Console.WriteLine("No network adapters found on this computer.");
return;
}
monitor.StartMonitoring();
for( int i = 0; i < 10; i ++)
{
foreach(NetworkAdapter adapter in adapters)
{
Console.WriteLine(adapter.Name);
Console.WriteLine(String.Format("dl: {0:n} " +
"kbps\t\tul: {1:n} kbps? adapter.DownloadSpeedKbps,
adapter.UploadSpeedKbps));
}
System.Threading.Thread.Sleep(1000); // Sleeps for one second.
}
// Stop the timer. Properties of adapter become invalid.
monitor.StopMonitoring ();
Points of Interest
To enumerate the network adapters on a computer, I only utilize the existing interface names in the networking category of performance console. Here is the EnumerateNetworkAdapters()
method.
private void EnumerateNetworkAdapters()
{
PerformanceCounterCategory category =
new PerformanceCounterCategory("Network Interface");
foreach (string name in category.GetInstanceNames())
{
if (name == "MS TCP Loopback interface")
continue;
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);
}
}
A tricky problem with this approach is that an instance called �MS TCP Loopback interface� exists on every computer, of which both the download speed and the upload speed are always zero. So I explicitly check and exclude it in the program, which is certainly not a good manner but workable.
Before all of this, I tried to accomplish this by making a WMI query, which looked more decent, and my first version went like this:
private void EnumerateNetworkAdapters()
{
ManagementObjectSearcher searcher = new
ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapter" +
" WHERE NetConnectionStatus=2");
ManagementObjectCollection adapterObjects = searcher.Get();
foreach (ManagementObject adapterObject in adapterObjects)
{
string name = adapterObject["Name"];
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);
}
}
The only problem is that the name of an adapter obtained this way will possibly differ from the instance name needed to create a performance counter. On my machine, this name is "Intel(R) PRO/100 VE Network Connection" querying WMI, and "Intel[R] Pro_100 VE Network Connection" in the performance console. I did not find a better solution and finally gave up WMI.