Welcome to the next installment of the .NET Nuts & Bolts column. This article explores some new items in the System.Net namespace, including the new System.Net.NetworkInformation namespace that will be included in the upcoming 2.0 release of the Microsoft .NET Framework. It adds support for some very useful network-related items, such as network address and traffic information, that were not included in the 1.0 and 1.1 versions of the base class library (BCL). The article explores some of these new items and how you can use them to your advantage.
Accessing Network Information About the Local Computer
The System.Net.NetworkInformation namespace contains a number of new classes that allow you to access network information about the local computer. The accessible information includes items such as the number of network cards configured on the machine and the configuration settings of each card. Many of the objects in the NetworkInformation namespace provide respective static GetXXX methods to retrieve instances of whatever configuration or information object they represent.
Network interface sample code
The following sample code demonstrates how to use some of the classes and methods. Its functionality serves as more of a diagnostic or informational display than any other real purpose. It enables you to get access to information such as MAC addresses, configured gateway and DNS settings, and so forth. Because a computer can have multiple interfaces, you start with a top-level collection of interfaces and work your way down to specifics:
using System; using System.Net.NetworkInformation; namespace NetworkChangesExample { class Program { static void Main(string[] args) { ShowNetworkInformation(); } public static void ShowNetworkInformation() { IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties(); Console.WriteLine("Host name: {0}", ipProperties.HostName); Console.WriteLine("Domain name: {0}", ipProperties.DomainName); foreach (NetworkInterface networkCard in NetworkInterface.GetAllNetworkInterfaces()) { Console.WriteLine("Interface: {0}", networkCard.Id); Console.WriteLine("t Name: {0}", networkCard.Name); Console.WriteLine("t Description: {0}", networkCard.Description); Console.WriteLine("t Status: {0}", networkCard.OperationalStatus); Console.WriteLine("t MAC Address: {0}", networkCard.GetPhysicalAddress().ToString()); Console.WriteLine("t Gateway Address:"); foreach (GatewayIPAddressInformation gatewayAddr in networkCard.GetIPProperties().GatewayAddresses) { Console.WriteLine("tt Gateway entry: {0}", gatewayAddr.Address.ToString()); } Console.WriteLine("t DNS Settings:"); foreach (IPAddress address in networkCard.GetIPProperties().DnsAddresses) { Console.WriteLine("tt DNS entry: {0}", address.ToString()); } Console.WriteLine("Current IP Connections:"); foreach (TcpConnectionInformation tcpConnection in IPGlobalProperties.GetIPGlobalProperties(). GetActiveTcpConnections()) { Console.WriteLine("t Connection Info:"); Console.WriteLine("tt Remote Address: {0}", tcpConnection.RemoteEndPoint. Address.ToString()); Console.WriteLine("tt State:", tcpConnection.State.ToString()); } } Console.ReadLine(); } } }
One of the things you’ll notice as you experiment with the classes is that there doesn’t appear to be a way to access the IP address assigned to a particular network card. I’m hoping that will change between now and the final release, or that I’ll be able to figure out where it is buried if it exists.
There is also an AddressChanged event for which you can provide an event handler to receive information about changes in address assignments in the event you want to capture when the assigned address changes for some reason.
Checking the Network Availability of Another Computer
The System.Net.NetworkInformation.Ping class allows you to check the accessibility of another computer over a TCP/IP-based network from managed code. Just as the name of the class indicates, it behaves similarly to the ping network command. It sends an ICMP echo request to a remote host and waits for an ICMP echo reply. Just as with the ping command, there is no guarantee the remote host is going to respond if there is a firewall between locations.
The Ping object supports both synchronous and asynchronous usage. A number of overloads of the Send and SendAsync accept parameters, allowing you to control things such as timeout, send a buffer of text to see how long it would take to transmit, and other options such as whether the request can be fragmented while in transit.
Ping sample code
The following sample code demonstrates the use of the Ping class. The Ping class is used to issue the ping request, and the response is returned in the PingReply class. The PingReply exposes a Status property that is an IpStatus enumerator containing various response types such as Success and TimedOut. I demonstrate a simple use of the class so as to show only functionality that is less likely to change. The code assumes you copy the TestPing method into the example class and add a call to TestPing in the Main method:
public static void TestPing() { Ping ping = new Ping(); PingReply pingReply = null; // Synchronously ping the local host Console.WriteLine("Pinging host: {0}", "127.0.0.1"); pingReply = ping.Send("127.0.0.1"); // Display the status result Console.WriteLine("Ping Status: {0}", pingReply.Status.ToString()); // Show the amount of time Console.WriteLine("Elapsed Time: {0}", pingReply.RoundTripTime); // Wait so we can see the output Console.ReadLine(); }