ネットワークの可用性

System.Net.NetworkInformation 名前空間を使用すると、ネットワーク イベント、変更、統計、プロパティについての情報を収集できます。 この記事では、System.Net.NetworkInformation.NetworkChange クラスを使用して、ネットワークのアドレスまたは可用性が変更されたかどうかを確認する方法について説明します。 さらに、インターフェイスまたはプロトコルを使用して、ネットワークの統計情報とプロパティを確認します。 最後に、System.Net.NetworkInformation.Ping クラスを使用して、リモート ホストに到達できるかどうかを確認します。

ネットワーク変更イベント

System.Net.NetworkInformation.NetworkChange クラスを使用して、ネットワークのアドレスまたは可用性が変更されたかどうかを確認できます。 このクラスを使用するには、変更を処理するイベント ハンドラーを作成し、それを NetworkAddressChangedEventHandler または 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;

前述の C# コードでは、次のことが行われます。

  • NetworkChange.NetworkAvailabilityChanged イベントのイベント ハンドラーを登録します。
  • このイベント ハンドラーは、可用性の状態をコンソールに書き込むだけです。
  • コンソールにメッセージを書き込み、コードがネットワーク可用性の変更をリッスンしていることをユーザーに知らせ、キーを押して終了するまで待機します。
  • イベント ハンドラーの登録を解除します。
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;

前述の C# コードでは、次のことが行われます。

  • NetworkChange.NetworkAddressChanged イベントのイベント ハンドラーを登録します。
  • このイベント ハンドラーは NetworkInterface.GetAllNetworkInterfaces() の反復処理を行い、その名前と操作状態をコンソールに書き込みます。
  • コンソールにメッセージを書き込み、コードがネットワーク可用性の変更をリッスンしていることをユーザーに知らせ、キーを押して終了するまで待機します。
  • イベント ハンドラーの登録を解除します。

ネットワークの統計情報とプロパティ

インターフェイスまたはプロトコルを使用して、ネットワークの統計情報とプロパティを収集できます。 NetworkInterfaceNetworkInterfaceTypePhysicalAddress の各クラスは、特定のネットワーク インターフェイスについての情報を提供します。一方、IPInterfacePropertiesIPGlobalPropertiesIPGlobalStatisticsTcpStatisticsUdpStatistics の各クラスは、レイヤー 3 とレイヤー 4 のパケットについての情報を提供します。

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

前述の C# コードでは、次のことが行われます。

リモート ホストに到達できるかどうかを確認する

Ping クラスを使用して、リモート ホストがネットワークで稼働しているかどうか、また到達できるかどうかを確認できます。

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

前述の C# コードでは、次のことが行われます。

  • Ping オブジェクトをインスタンス化します。
  • ホスト名パラメーター "stackoverflow.com" を指定して Ping.SendPingAsync(String) を呼び出します。
  • ping の状態がコンソールに書き込まれます。

関連項目