Click here to Skip to main content
15,867,308 members
Articles / Programming Languages / C#

.NET Network Monitor

Rate me:
Please Sign up or sign in to vote.
4.73/5 (20 votes)
22 Jul 2011CPOL3 min read 120.1K   12.8K   93   20
A simple network monitor.

Introduction

In this article, I will present my custom class NetworkManager and explain my design idea. And I will present other references, that is using the Win32 API InternetGetConnectedState and the .NET Framework NetworkInterface, but at last, I will not use InternetGetConnectedState and NetworkInterface.

In here, you will learn these techniques.

Background

I need to monitor the network status in my project. This is to check if the cable has a bad contact or not and to check if the network is enabled or not. So I developed a simple tool to test.

Why do I need to monitor the network status? Because in our product, we had an issue where the cable had a bad contact with the network vard. So the user requested for a solution and we talked about this issue in our team meeting. We thought we needed a complete solution, and maybe the user will also disable the network in the environment.

Using the Code

I use a singleton to manage all the network information. Now, call this code to initialize and monitor:

C#
NetworkManager.Instance.StartMonitor();

And foreach NetworkManager.Instance.Informations.Values to get the required information:

C#
foreach(NetworkInfo info in NetworkManager.Instance.Informations.Values)
{
    Console.WriteLine("Device Name:" + info.DeviceName);
    Console.WriteLine("Adapter Type:" + info.AdapterType);
    Console.WriteLine("MAC Address:" + info.MacAddress);
    Console.WriteLine("Connection Name:" + info.ConnectionID);
    Console.WriteLine("IP Address:" + info.IP);
    Console.WriteLine("Connection Status:" + info.Status.ToString());
}

At last call this to destroy:

C#
NetworkManager.Instance.Destory();

About the Code

C#
public enum NetConnectionStatus
{
    Disconnected = 0,
    Connecting = 1,
    Connected = 2,
    Disconnecting = 3,
    HardwareNotPresent = 4,
    HardwareDisabled = 5,
    HardwareMalfunction = 6,
    MediaDisconnected = 7,
    Authenticating = 8,
    AuthenticationSucceeded = 9,
    AuthenticationFailed = 10,
    InvalidAddress = 11,
    CredentialsRequired = 12
}

First, the enum named NetConnectionStatus that is a reference from the property NetConnectionStatus in the Win32NetworkAdapter class.

In my project, I need the information, so I declared it.

C#
static readonly NetworkManager m_instance = new NetworkManager();

I use singleton for NetworkManager, because I think this class will get the information as network cards, and all instances will get the same information, so singleton is the best.

C#
static NetworkManager()
{
    ManagementObjectSearcher searcher = new ManagementObjectSearcher(
        "SELECT * FROM Win32_NetworkAdapter WHERE NetConnectionID IS NOT NULL");
    foreach (ManagementObject mo in searcher.Get())
    {
        NetworkInfo info = new NetworkInfo();
        info.DeviceName = ParseProperty(mo["Description"]);
        info.AdapterType = ParseProperty(mo["AdapterType"]);
        info.MacAddress = ParseProperty(mo["MACAddress"]);
        info.ConnectionID = ParseProperty(mo["NetConnectionID"]);
        info.Status = (NetConnectionStatus)Convert.ToInt32(mo["NetConnectionStatus"]);
        SetIP(info);
        m_Informations.Add(info.ConnectionID, info);
    }
}
C#
static void SetIP(NetworkInfo info)
{
    ManagementClass objMC = 
       new ManagementClass("Win32_NetworkAdapterConfiguration");
    foreach (ManagementObject mo in objMC.GetInstances())
    {
        try
        {
            if (!(bool)mo["ipEnabled"])
                continue;
            if (mo["MACAddress"].ToString().Equals(info.MacAddress))
            {
                string[] ip = (string[])mo["IPAddress"];
                info.IP = ip[0];
                string[] mask = (string[])mo["IPSubnet"];
                info.Mask = mask[0];
                string[] gateway = (string[])mo["DefaultIPGateway"];
                info.DefaultGateway = gateway[0];
                break;
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine("[SetIP]:" + ex.Message);
        }
    }
}

The ConnectionID will show in the Windows Console, so I use the property to be a key.

I use ManagementObjectSearcher to get the network card information in Win32_NetworkAdapter, but IP, subnet, and gateway is available in Win32_NetworkAdapterConfiguration.

WQL can't use the join table, so I use the SetIP function that will get the IP address in Win32_NetworkAdapterConfiguration by MACAddress, because MACAddress exists in Win32_NetworkAdapter and Win32_NetworkAdapterConfiguration.

Executing Image

When we disable the network in the Console, the Monitor will get the disconnect status.

11.JPG

When the cable has a bad contact, it gets that information.

13.JPG

This is when the Connect succeeds:

12.JPG

Points of Interest

Apart from WMI, I also try InternetGetConnectedState API and NetworkInterface.

C#
public class WinINET
{
    [DllImport("wininet.dll", SetLastError = true)]
    public extern static bool InternetGetConnectedState(out int lpdwFlags,
        int dwReserved);

    [Flags]
    public enum ConnectionStates
    {
        Modem = 0x1,
        LAN = 0x2,
        Proxy = 0x4,
        RasInstalled = 0x10,
        Offline = 0x20,
        Configured = 0x40,
    }
}
C#
static void WinINETAPI()
{
    int flags;
    bool isConnected = WinINET.InternetGetConnectedState(out flags, 0);
    Console.WriteLine(string.Format("Is connected :{0} Flags:{1}", isConnected,
        ((WinINET.ConnectionStates)flags).ToString()));
}

When I try the InternetGetConnectedState API, I find the API already returns true when I disable a network card. (I have two network cards.)

In my project, the front-end will get the client's data with LAN but the front end also needs to connect to the WAN with another network card. So I think this function will not help me handle all the network status. If you want to use an API in .NET, you must use DllImport to declare the API.

The enum ConnectionStates is a flag value, converts flags to ConnectionStates, and using ToString(), we can get the required information.

For example, when flags = 0x18, convert to ConnectionStates and using ToString() will get the "LAN,RasInstalled" string.

C#
static void NetInfo()
{
    foreach (NetworkInterface face in 
             NetworkInterface.GetAllNetworkInterfaces())
    {
        Console.WriteLine("=================================================");
        Console.WriteLine(face.Id);
        Console.WriteLine(face.Name);
        Console.WriteLine(face.NetworkInterfaceType.ToString());
        Console.WriteLine(face.OperationalStatus.ToString());
        Console.WriteLine(face.Speed);
    }
}

Here are the two network cards in my PC.

When I use this code to get network information and the network is connected, it will display the information. The OperationalStatus property will show up. And it will get Down when I remove the cable from the network card.

But I think the perfect solution not just handles the network cable, so I tried to disable the network in the Windows Console. After disabling the network, I run the code again, but it doesn't show the disabled network card's information.

So I think NetworkInterface may not be a perfect solution.

History

  • V1.3: Updated information and background.
  • V1.2: Updated source code project.
  • V1.1: Added more detail.
  • V1.0: Added code for Network Monitor.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect SIS
Taiwan Taiwan
CloudBox cross-platform framework. (iOS+ Android)
Github: cloudhsu
My APP:
1. Super Baby Pig (iOS+Android)
2. God Lotto (iOS+Android)
2. Ninja Darts (iOS)
3. Fight Bingo (iOS)

Comments and Discussions

 
QuestionVirus? Pin
John Dovey12-Mar-21 5:44
John Dovey12-Mar-21 5:44 
AnswerRe: Virus? Pin
tgueth14-Oct-21 4:52
professionaltgueth14-Oct-21 4:52 
GeneralRe: Virus? Pin
C T 20216-Dec-21 12:37
C T 20216-Dec-21 12:37 
GeneralRe: Virus? Pin
FabrizioFBA24-Jul-22 23:33
FabrizioFBA24-Jul-22 23:33 
GeneralRe: Virus? Pin
C T 202125-Sep-22 15:32
C T 202125-Sep-22 15:32 
GeneralNo Need! Pin
Rock (Multithreaded)8-Mar-14 11:19
Rock (Multithreaded)8-Mar-14 11:19 
QuestionOk, that,s fine. I have a question Pin
Abo_Yousuf27-Mar-12 4:10
Abo_Yousuf27-Mar-12 4:10 
AnswerRe: Ok, that,s fine. I have a question Pin
Cloud Hsu27-Jun-12 19:57
Cloud Hsu27-Jun-12 19:57 
AnswerRe: Ok, that,s fine. I have a question Pin
Cloud Hsu27-Jun-12 19:58
Cloud Hsu27-Jun-12 19:58 
QuestionI love your iPhone apps Pin
Sacha Barber19-Jul-11 21:58
Sacha Barber19-Jul-11 21:58 
AnswerRe: I love your iPhone apps Pin
Cloud Hsu20-Jul-11 3:12
Cloud Hsu20-Jul-11 3:12 
Thank you very much! Smile | :)
SuggestionJust so you know Pin
Adrian Cole19-Jul-11 9:22
Adrian Cole19-Jul-11 9:22 
GeneralRe: Just so you know Pin
Cloud Hsu19-Jul-11 16:17
Cloud Hsu19-Jul-11 16:17 
GeneralRe: Just so you know Pin
Adrian Cole20-Jul-11 8:45
Adrian Cole20-Jul-11 8:45 
GeneralMy vote of 5 Pin
TweakBird19-Jul-11 4:38
TweakBird19-Jul-11 4:38 
GeneralRe: My vote of 5 Pin
Cloud Hsu20-Jul-11 5:52
Cloud Hsu20-Jul-11 5:52 
GeneralMy vote of 5 Pin
Claudio Nicora18-Jul-11 23:09
Claudio Nicora18-Jul-11 23:09 
GeneralRe: My vote of 5 Pin
Cloud Hsu19-Jul-11 16:24
Cloud Hsu19-Jul-11 16:24 
GeneralMy vote of 4 Pin
skv_lviv15-Jul-11 21:47
skv_lviv15-Jul-11 21:47 
GeneralRe: My vote of 4 Pin
Cloud Hsu17-Jul-11 22:14
Cloud Hsu17-Jul-11 22:14 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.