Access Newly Available Network Information with .NET 2.0

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("\t\t Gateway entry: {0}",
                                 gatewayAddr.Address.ToString());
            }

            Console.WriteLine("\t DNS Settings:");
            foreach (IPAddress address in
                     networkCard.GetIPProperties().DnsAddresses)
            {
               Console.WriteLine("\t\t DNS entry: {0}",
                                 address.ToString());
            }

            Console.WriteLine("Current IP Connections:");
            foreach (TcpConnectionInformation tcpConnection in
                     IPGlobalProperties.GetIPGlobalProperties().
                     GetActiveTcpConnections())
            {
               Console.WriteLine("\t Connection Info:");
               Console.WriteLine("\t\t Remote Address: {0}",
                                 tcpConnection.RemoteEndPoint.
                                 Address.ToString());
               Console.WriteLine("\t\t 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();
}

Access Newly Available Network Information with .NET 2.0

Using File Transfer Protocol (FTP)

One of the features missing from the BCL has been the ability to support FTP requests. This has been rectified with the addition of the FtpWebRequest object, which provides a managed interface for issuing FTP commands. It is included in System.Net namespace. The Create method of the WebRequest class is used to retrieve an instance of FtpWebRequest, which can then be used for various FTP operations.

FTP sample code

The following sample code connects to the local machine via FTP and downloads a specific file. This assumes you have FTP running on your local machine and a text file exists with the particular name. The FtpWebRequest has a Method property on it that is used to specify the action to take. By default, the action is FtpMethods.DownloadFile, so it is not necessary to set the property value. The code assumes you copy the TestFtp method into the example class and add a call to TestFtp in the Main method:

public static void TestFtp()
{
   // Set up the FTP connection
   FtpWebRequest ftpRequest =
      (FtpWebRequest)WebRequest.Create("ftp://localhost/testfile.txt");
   ftpRequest.Credentials = new
      NetworkCredential("anonymous", "mstrawmyer@crowechizek.com");

   // Initiate the request and read the response
   FtpWebResponse ftpResponse =
      (FtpWebResponse)ftpRequest.GetResponse();
   Stream ftpResponseStream = ftpResponse.GetResponseStream();
   StreamReader reader = new StreamReader(ftpResponseStream,
                                          System.Text.Encoding.UTF8);

   // Display the file contents
   Console.WriteLine(reader.ReadToEnd());
   Console.ReadLine();
}

Simplified FTP sample code

There is an easier way to perform downloads from an FTP site using the WebClient object. The following sample code demonstrates using it to download the same file accessed in the prior example. As you can see, it is definitely a simplified approach. The code assumes you copy the TestSimpleFtp method into the example class and add a call to TestSimpleFtp in the Main method:

public static void TestSimpleFtp()
{
   WebClient client = new WebClient();
   client.Credentials = new NetworkCredential("anonymous",
                                              "mstrawmyer@crowechizek.com");
   client.DownloadFile("ftp://localhost/testfile.txt", "C:\\Demofile.txt");
}

Future Columns

The topic of the next column has yet to be determined. If you have something in particular that you would like to see explained, please e-mail me at mstrawmyer@crowechizek.com.



About the Author

Mark Strawmyer

Mark Strawmyer is a Senior Architect of .NET applications for large and mid-size organizations. He specializes in architecture, design and development of Microsoft-based solutions. Mark was honored to be named a Microsoft MVP for application development with C# for the fifth year in a row. You can reach Mark at mark.strawmyer@crowehorwath.com.

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • With JRebel, developers get to see their code changes immediately, fine-tune their code with incremental changes, debug, explore and deploy their code with ease (both locally and remotely), and ultimately spend more time coding instead of waiting for the dreaded application redeploy to finish. Every time a developer tests a code change it takes minutes to build and deploy the application. JRebel keeps the app server running at all times, so testing is instantaneous and interactive.

  • Live Event Date: April 22, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT Database professionals — whether developers or DBAs — can often save valuable time by learning to get the most from their new or existing productivity tools. Whether you're responsible for managing database projects, performing database health checks and reporting, analyzing code, or measuring software engineering metrics, it's likely you're not taking advantage of some of the lesser-known features of Toad from Dell. Attend this live …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds