网络可用性
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(),将其名称和操作状态写入控制台。
- 将一条消息写入控制台,让用户知晓代码正在侦听网络可用性的更改,然后等待按键退出。
- 取消注册事件处理程序。
网络统计信息和属性
可在接口或协议基础上收集网络统计信息和属性。 NetworkInterface、NetworkInterfaceType 和 PhysicalAddress 类提供有关特定网络接口的信息,而 IPInterfaceProperties、IPGlobalProperties、IPGlobalStatistics、TcpStatistics 和 UdpStatistics 类提供有关第 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# 代码:
- 调用自定义
ShowStatistics
方法以显示每个协议的统计信息。 ShowStatistics
方法调用 IPGlobalProperties.GetIPGlobalProperties(),具体取决于给定的 NetworkInterfaceComponent 将调用 IPGlobalProperties.GetIPv4GlobalStatistics() 还是 IPGlobalProperties.GetIPv6GlobalStatistics()。- TcpStatistics 将写入控制台。
确定是否可访问远程主机
可使用 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 的状态将写入控制台。