dcsimg
November 25, 2020
Hot Topics:

Creating a Network Speed Monitor in C#

  • By Hannes Du Preez
  • Send Email »
  • More Articles »

It's always handy to know exactly how much download and upload speed your current network has. This article will show you how to create a Class library project that will host the Uploading and Downloading logic, and a normal Console application making use of the external library to display the results.

So, let’s get straight into it.

Creating the Class library

Make use of the following steps to create a Class Library.

  • Open Visual Studio
  • Select File, New Project - if necessary
  • Select Class Library from the C# template options
  • Name the Class Library NetMon_Ex
  • Ensure it has two classes named:
    • NM_Adapter.cs
    • NM_Monitor.cs

Once both classes are created, we have to enter code. Let’s start with the NM_Monitor class.

NM_Adapter.cs

This class is used to create the necessary methods and properties needed in order to determine what the upload and download speeds are as well as the current network adapter name. Here is its code:

using System;
using System.Diagnostics;

namespace NetMon_Ex
{

	public class NM_Adapter
    {

		internal NM_Adapter(string strName) 
        {
			strAdapterName	=	strName;
		}

        private long lngDownloadSpeed;
        private long lngUploadSpeed;
        private long lngDownloadValue;
        private long lngUploadValue;
        private long lngOldDownloadValue;
        private long lngOldUploadValue;

		internal string strAdapterName;
        internal PerformanceCounter pcDownloadCounter; 
        internal PerformanceCounter pcUploadCounter;

		internal void Initialize()
		{
			lngOldDownloadValue = pcDownloadCounter.NextSample().RawValue;
			lngOldUploadValue = pcUploadCounter.NextSample().RawValue;
		}

		internal void Update()
		{
			lngDownloadValue =	pcDownloadCounter.NextSample().RawValue;
			lngUploadValue	= pcUploadCounter.NextSample().RawValue;
			
			lngDownloadSpeed = lngDownloadValue - lngOldDownloadValue;
			lngUploadSpeed = lngUploadValue - lngOldUploadValue;

			lngOldDownloadValue	= lngDownloadValue;
			lngOldUploadValue = lngUploadValue;
		}

		public override string ToString()
		{
			return this.strAdapterName;
		}

		public string AdapterName
		{
			get
			{
				return strAdapterName;
			}
		}

		public long DownloadSpeed
		{
			get
			{
				return lngDownloadSpeed;
			}
		}

		public long UploadSpeed
		{
			get
			{
				return lngUploadSpeed;
			}
		}

		public double DownloadSpeedKbps
		{
			get
			{
				return lngDownloadSpeed / 1024.0;
			}
		}

		public double UploadSpeedKbps
		{
			get
			{
				return lngUploadSpeed / 1024.0;
			}
		}
	}
}

Quite straight forward. Now, let’s add the NM_Monitor class code

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

namespace NetMon_Ex
{

	public class NM_Monitor
    {
		private Timer tmrTime;	
		private ArrayList alAdapters;	
		private ArrayList alAdaptersMonitored;	

		public NM_Monitor()
		{
			alAdapters = new ArrayList();
			alAdaptersMonitored	= new ArrayList();

			LoopAdapters();
			
			tmrTime	= new Timer(1000);
			tmrTime.Elapsed	+=	new ElapsedEventHandler(tmrTime_Elapsed);
		}

		private void LoopAdapters()
		{

            PerformanceCounterCategory pcNetworkInterface = new PerformanceCounterCategory("Network Interface");

			foreach (string tmpName in pcNetworkInterface.GetInstanceNames())
			{

				if (tmpName == "MS TCP Loopback interface")
					continue;

                NM_Adapter netAdapter = new NM_Adapter(tmpName);

				netAdapter.pcDownloadCounter = new PerformanceCounter("Network Interface", "Bytes Received/sec", tmpName);
				netAdapter.pcUploadCounter = new PerformanceCounter("Network Interface", "Bytes Sent/sec", tmpName);

                alAdapters.Add(netAdapter);	
			}
		}

		private void tmrTime_Elapsed(object sender, ElapsedEventArgs e)
		{
			foreach (NM_Adapter tmpAdapter in alAdaptersMonitored)
				tmpAdapter.Update();
		}

		public NM_Adapter[] arrAdapters
		{
			get
			{
				return (NM_Adapter[])alAdapters.ToArray(typeof(NM_Adapter));
			}
		}

		public void Start()
		{
			if (this.alAdapters.Count > 0)
			{
				foreach(NM_Adapter currAdapter in alAdapters)

					if (!alAdaptersMonitored.Contains(currAdapter))
					{
						alAdaptersMonitored.Add(currAdapter);
						currAdapter.Initialize();
					}
				
				tmrTime.Enabled	=	true;
			}
		}

		public void Start(NM_Adapter nmAdapter)
		{
			if (!alAdaptersMonitored.Contains(nmAdapter))
			{
				alAdaptersMonitored.Add(nmAdapter);
				nmAdapter.Initialize();
			}

			tmrTime.Enabled	=	true;
		}

		public void Stop()
		{
			alAdaptersMonitored.Clear();
			tmrTime.Enabled	=	false;
		}

		public void Stop(NM_Adapter currAdapter)
		{
			if (alAdaptersMonitored.Contains(currAdapter))
				alAdaptersMonitored.Remove(currAdapter);
            
			if(alAdaptersMonitored.Count == 0)
				tmrTime.Enabled	= false;
		}
	}
}

This class enables the NM_Adapter class to do its work. It includes the Start and Stop methods that refreshes or updates the current upload or download info.

Build this class.

After building, it should produce a DLL file containing this logic and can be used from outside applications.

Console Application

Create a Console C# application and name it NetMon_App for example.

After it has loaded, set a Reference to the DLL created earlier. You create a Reference by right clicking on the Solution Explorer and selecting Add reference. An example screenshot of the reference is shown next:


Figure 1 - DLL Reference

Edit the Program.cs file to resemble the following:

using NetMon_Ex;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NetMon_App
{
    class Program
    {
        static void Main(string[] args)
        {
            NM_Monitor nmMonitor = new NM_Monitor();
            NM_Adapter[] arrAdapters = nmMonitor.arrAdapters;


            if (arrAdapters.Length == 0)
            {
                Console.WriteLine("No network adapters found.");
                return;
            }

            nmMonitor.Start();

            for (int i = 0; i < 10; i++)
            {
                foreach (NM_Adapter tmpAdapter in arrAdapters)
                {

                    Console.WriteLine(tmpAdapter.AdapterName);

                    Console.WriteLine("Download: " + tmpAdapter.DownloadSpeedKbps.ToString() + " kbps " + Environment.NewLine +
                       "Upload: " + tmpAdapter.UploadSpeedKbps + " kbps ");
                }

                System.Threading.Thread.Sleep(1000); 
            }

            nmMonitor.Stop();
        }
    }
}

The above code creates an array of adapters and a new Monitor object, then starts monitoring. Inside the loop it continuously updates the output screen with the Adapter name and the download and upload speeds. This is shown next:

Text

Description automatically generated
Figure 2 - Running

Conclusion

Easier than you thought? Of course! Most of the time we as programmers tend to overcomplicate things, but I suppose that is how most of us wired. I hope you have learned from this article.

 





This article was originally published on November 13, 2020

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.


Thanks for your registration, follow us on our social networks to keep up-to-date