Click here to Skip to main content
Click here to Skip to main content

.NET Network Monitor

By , 22 Jul 2011
 

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:

NetworkManager.Instance.StartMonitor();

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

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:

NetworkManager.Instance.Destory();

About the Code

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.

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.

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);
    }
}
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.

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,
    }
}
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.

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)

About the Author

Cloud Hsu
Architect LPI
Taiwan Taiwan
Member
CloudBox cross-platform framework. (iOS+ Android)
My APP:
1. Super Baby Pig (iOS+Android)
2. God Lotto (iOS+Android)
2. Ninja Darts (iOS)
3. Fight Bingo (iOS)

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionOk, that,s fine. I have a questionmemberAbo_Yousuf27 Mar '12 - 4:10 
Could we have code for name of wireless network names in C#
AnswerRe: Ok, that,s fine. I have a questionmemberCloud Hsu27 Jun '12 - 19:57 
You can use the NetworkInterfaceType property of the NetworkInterface class.
It will be equal to NetworkInterfaceType.Wireless80211 if the interface represents a WiFi adapter.
AnswerRe: Ok, that,s fine. I have a questionmemberCloud Hsu27 Jun '12 - 19:58 
http://msdn.microsoft.com/zh-tw/library/system.net.networkinformation.networkinterfacetype.aspx[^]
QuestionI love your iPhone appsmvpSacha Barber19 Jul '11 - 21:58 
They are cool
Sacha Barber
  • Microsoft Visual C# MVP 2008-2011
  • Codeproject MVP 2008-2011
Open Source Projects
Cinch SL/WPF MVVM

Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue
 
My Blog : sachabarber.net

AnswerRe: I love your iPhone appsmemberCloud Hsu20 Jul '11 - 3:12 
Thank you very much! Smile | :)
SuggestionJust so you knowmemberAdrian Cole19 Jul '11 - 9:22 
I believe you can accomplish the same thing using classes in the System.Net.NetworkInformation namespace. It's been around since .NET 3.0
while (e) { Coyote(); }

GeneralRe: Just so you knowmemberCloud Hsu19 Jul '11 - 16:17 
I tried it and post in my article. Smile | :)
But I can get any information by NetworkInformation when I disable network in Windows Console.
Do you share any experience ? Smile | :)
GeneralRe: Just so you knowmemberAdrian Cole20 Jul '11 - 8:45 
I hadn't tried enumerating disabled interfaces before. I just tried it now and you are right, they don't show up.
while (e) { Coyote(); }

GeneralMy vote of 5memberTweakBird19 Jul '11 - 4:38 
Good article.
GeneralRe: My vote of 5memberCloud Hsu20 Jul '11 - 5:52 
thank you very much! Smile | :)
GeneralMy vote of 5memberClaudio Nicora18 Jul '11 - 23:09 
Really interesting!
 
PS: title "Abort the code" should read "About the code"... Wink | ;)
GeneralRe: My vote of 5memberCloud Hsu19 Jul '11 - 16:24 
fix it, thank you. Smile | :)
GeneralMy vote of 4memberskv_lviv15 Jul '11 - 21:47 
Good, but putting just 4 because code didn't compile - WinINET.cs wasn't included into project and some usings were missing
GeneralRe: My vote of 4memberCloud Hsu17 Jul '11 - 22:14 
already update source code Smile | :)

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

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130516.1 | Last Updated 22 Jul 2011
Article Copyright 2011 by Cloud Hsu
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid