CloudHow to Create a Network Speed Monitor in C#

How to Create a Network Speed Monitor in C#

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

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 1DLL 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 2Running

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.

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories