Network availability

The System.Net.NetworkInformation namespace enables you to gather information about network events, changes, statistics, and properties. In this article, you'll learn how to use the System.Net.NetworkInformation.NetworkChange class to determine whether the network address or availability has changed. Additionally, you'll see about the network statistics and properties on an interface or protocol basis. Finally, you'll use the System.Net.NetworkInformation.Ping class to determine whether a remote host is reachable.

Network change events

The System.Net.NetworkInformation.NetworkChange class enables you to determine whether the network address or availability has changed. To use this class, create an event handler to process the change, and associate it with a NetworkAddressChangedEventHandler or a NetworkAvailabilityChangedEventHandler.

NetworkChange.NetworkAvailabilityChanged += OnNetworkAvailabilityChanged;

static void OnNetworkAvailabilityChanged(
    object? sender, NetworkAvailabilityEventArgs networkAvailability) =>
    Console.WriteLine($"Network is available: {networkAvailability.IsAvailable}");

Console.WriteLine(
    "Listening changes in network availability. Press any key to continue.");
Console.ReadLine();

NetworkChange.NetworkAvailabilityChanged -= OnNetworkAvailabilityChanged;

The preceding C# code:

  • Registers an event handler for the NetworkChange.NetworkAvailabilityChanged event.
  • The event handler simply writes the availability status to the console.
  • A message is written to the console letting the user know that the code is listening for changes in network availability and waits for a key press to exit.
  • Unregisters the event handler.
NetworkChange.NetworkAddressChanged += OnNetworkAddressChanged;

static void OnNetworkAddressChanged(
    object? sender, EventArgs args)
{
    foreach ((string name, OperationalStatus status) in
        NetworkInterface.GetAllNetworkInterfaces()
            .Select(networkInterface =>
                (networkInterface.Name, networkInterface.OperationalStatus)))
    {
        Console.WriteLine(
            $"{name} is {status}");
    }
}

Console.WriteLine(
    "Listening for address changes. Press any key to continue.");
Console.ReadLine();

NetworkChange.NetworkAddressChanged -= OnNetworkAddressChanged;

The preceding C# code:

  • Registers an event handler for the NetworkChange.NetworkAddressChanged event.
  • The event handler iterates over NetworkInterface.GetAllNetworkInterfaces(), writing their name and operational status to the console.
  • A message is written to the console letting the user know that the code is listening for changes in network availability and waits for a key press to exit.
  • Unregisters the event handler.

Network statistics and properties

You can gather network statistics and properties on an interface or protocol basis. The NetworkInterface, NetworkInterfaceType, and PhysicalAddress classes give information about a particular network interface, while the IPInterfaceProperties, IPGlobalProperties, IPGlobalStatistics, TcpStatistics, and UdpStatistics classes give information about layer 3 and layer 4 packets.

ShowStatistics(NetworkInterfaceComponent.IPv4);
ShowStatistics(NetworkInterfaceComponent.IPv6);

static void ShowStatistics(NetworkInterfaceComponent version)
{
    var properties = IPGlobalProperties.GetIPGlobalProperties();
    var stats = version switch
    {
        NetworkInterfaceComponent.IPv4 => properties.GetTcpIPv4Statistics(),
        _ => properties.GetTcpIPv6Statistics()
    };

    Console.WriteLine($"TCP/{version} Statistics");
    Console.WriteLine($"  Minimum Transmission Timeout : {stats.MinimumTransmissionTimeout:#,#}");
    Console.WriteLine($"  Maximum Transmission Timeout : {stats.MaximumTransmissionTimeout:#,#}");
    Console.WriteLine("  Connection Data");
    Console.WriteLine($"      Current :                  {stats.CurrentConnections:#,#}");
    Console.WriteLine($"      Cumulative :               {stats.CumulativeConnections:#,#}");
    Console.WriteLine($"      Initiated  :               {stats.ConnectionsInitiated:#,#}");
    Console.WriteLine($"      Accepted :                 {stats.ConnectionsAccepted:#,#}");
    Console.WriteLine($"      Failed Attempts :          {stats.FailedConnectionAttempts:#,#}");
    Console.WriteLine($"      Reset :                    {stats.ResetConnections:#,#}");
    Console.WriteLine("  Segment Data");
    Console.WriteLine($"      Received :                 {stats.SegmentsReceived:#,#}");
    Console.WriteLine($"      Sent :                     {stats.SegmentsSent:#,#}");
    Console.WriteLine($"      Retransmitted :            {stats.SegmentsResent:#,#}");
    Console.WriteLine();
}

The preceding C# code:

Determine if a remote host is reachable

You can use the Ping class to determine whether a remote host is up, on the network, and reachable.

using Ping ping = new();

string hostName = "stackoverflow.com";
PingReply reply = await ping.SendPingAsync(hostName);
Console.WriteLine($"Ping status for ({hostName}): {reply.Status}");
if (reply is { Status: IPStatus.Success })
{
    Console.WriteLine($"Address: {reply.Address}");
    Console.WriteLine($"Roundtrip time: {reply.RoundtripTime}");
    Console.WriteLine($"Time to live: {reply.Options?.Ttl}");
    Console.WriteLine();
}

The preceding C# code:

  • Instantiate a Ping object.
  • Calls Ping.SendPingAsync(String) with the "stackoverflow.com" hostname parameter.
  • The status of the ping is written to the console.

See also