Wednesday, November 24, 2010

Asynchronous Method: AsyncResolve.cs program

The AsyncResolve.cs program
Start example
using System;
using System.Drawing;
using System.Net;
using System.Text;
using System.Windows.Forms;
class AsyncResolve    Form:
{
  TextBox address;
  ListBox results;
  private AsyncCallback OnResolved;
  public AsyncResolve()
  {
   Text = "DNS Address Resolver";
   Size = new Size(400,380);
   OnResolved = new AsyncCallback(Resolved);
   Label label1 = new Label();
   label1.Parent = this;
   label1.Text = "Enter address to resolve:";
   label1.AutoSize = true;
   label1.Location = new Point(10, 10);
   address = new TextBox();
   address.Parent = this;
   address.Size = new Size(200, 2 * Font.Height);
   address.Location = new Point(10, 35);
   results = new ListBox();
   results.Parent = this;
   results.Location = new Point(10, 65);
   results.Size = new Size(350, 20 * Font.Height);
   Button checkit = new Button();
   checkit.Parent = this;
   checkit.Text = "Resolve";
   checkit.Location = new Point(235,32);
   checkit.Size = new Size(7 * Font.Height, 2 * Font.Height);
   checkit.Click += new EventHandler(ButtonResolveOnClick);
  }
  void ButtonResolveOnClick(object obj, EventArgs ea)
  {
   results.Items.Clear();
   string addr = address.Text;
   Object state = new Object();
   Dns.BeginResolve(addr, OnResolved, state);
  }
  private void Resolved(IAsyncResult ar)
  {
   string buffer;
   IPHostEntry iphe = Dns.EndResolve(ar);
   buffer = "Host name: " + iphe.HostName;
   results.Items.Add(buffer);
   foreach(string alias in iphe.Aliases)
   {
     buffer = "Alias: " + alias;
     results.Items.Add(buffer);
   }
   foreach(IPAddress addrs in iphe.AddressList)
   {
     buffer = "Address: " + addrs.ToString();
     results.Items.Add(buffer);
   }
  }
  public static void Main()
  {
   Application.Run(new AsyncResolve());
  }
}

Asynchronous Methods

The regular Dns methods might cause a problem for your C# program because they use blocking mode to communicate with the remote DNS server. If you ran the example programs offered earlier in this section on the DNS classes, you may have noticed that it often takes a few seconds for the DNS information to be returned from the remote DNS server. This may not seem like much of a problem, but it can cause serious difficulties in Windows programs that allow the user to do other things at the same time. While the program is waiting for the DNS server response, the user is prevented from clicking any buttons or entering any information in TextBox fields. For some applications, this can mean unacceptable performance.

The Dns class provides the following asynchronous methods to allow your programs to perform asynchronous DNS function calls:
  • BeginGetHostByName()
  • BeginResolve()
  • EndGetHostByName()
  • EndResolve()
Each of the asynchronous methods parallels the equivalent synchronous method. At this time there is no asynchronous GetHostByAddress() call.
The methods are called in pairs. The Beginxxx method is called from the program and points to a delegate method, which contains the Endxxx method. For example, BeginResolve() uses the following format:
public static IAsyncResult BeginResolve(string hostname,
AsyncCallback requestCallback, object stateObject)
The method uses three parameters:
  • A string representation, hostname, of a hostname or IP address
  • An AsyncCallback object, requestCallback, which defines the delegate
  • A generic object, stateObject, which defines the method state
The AsyncCallback object is created to point to the delegate method used when the DNS results are returned. To do this, you must first create the AsyncCallback object, then assign the delegate method to it:
private AsyncCallback OnResolved;
OnResolved = new AsyncCallback(Resolved);
Object state = new Object(); . .
, state); . } private void Resolved(Iasync
Dns.BeginResolve(addr, OnResolve dResult ar) { IPHostEntry iphe = Dns.EndResolve(ar);
}
The OnResolved AsyncCallback object points to the delegate method Resolved, which will contain the EndResolve() method to complete the DNS call. The state object allows you to pass information to the delegate method. The EndResolve() method has this format:
public static IPHostEntry EndResolve(IasyncResult ar)
The IAsyncResult object ar is what refers the EndResolve() method to the original BeginResolve() method. The result of the EndResolve() method is the standard IPHostEntry object, which can then be broken down to extract the returned information, similar to the standard Resolve() method discussed earlier

C Sharp programs for Get DNS host and address informastion

The GetDNSHostInfo.cs program
Start example
using System;
using System.Net;
class GetDNSHostInfo
{
  public static void Main(string[] argv)
  {
   if (argv.Length != 1)
   {
    Console.WriteLine("Usage: GetDNSHostInfo hostname");
    return;
   }
   IPHostEntry results = Dns.GetHostByName(argv[0]);
   Console.WriteLine("Host name: {0}",
            results.HostName);
   foreach(string alias in results.Aliases)
   {
     Console.WriteLine("Alias: {0}", alias);
   }
   foreach(IPAddress address in results.AddressList)
   {
     Console.WriteLine("Address: {0}",
           address.ToString());
   }
  }
}
The GetDNSAddressInfo.cs program 
Start example
using System;
using System.Net;
class GetDNSAddressInfo
{
  public static void Main(string)[] argv)
  {
   if (argv.Length != 1)
   {
     Console.WriteLine("Usage: GetDNSAddressInfo address");
     return;
   }
   IPAddress test = IPAddress.Parse(argv[0]);
   IPHostEntry iphe = Dns.GetHostByAddress(test);
   Console.WriteLine("Information for {0}",
           test.ToString());
   Console.WriteLine("Host name: {0}", iphe.HostName);
   foreach(string alias in iphe.Aliases)
   {
     Console.WriteLine("Alias: {0}", alias);
   }
   foreach(IPAddress address in iphe.AddressList)
   {
     Console.WriteLine("Address: {0}", address.ToString());
   }
  }
}

DNS Classes in C#

The System.Net namespace contains the Dns class, which provides all the necessary DNS functions for C# programs. This section describes the Dns class methods and shows how they can be used in C# programs to utilize the DNS capabilities of the system.

Synchronous Methods

There are four synchronous methods defined in the Dns class:
  • GetHostName()
  • GetHostByName()
  • GetHostByAddress()
  • Resolve()

GetHostName()

The GetHostName() method is used to determine the hostname of the local system the program is running on. This information is frequently needed for network programs, so you’ll see this method used a lot. The format is simple: there are no parameters to enter, and the result is a string object:
string hostname = Dns.GetHostName();
The information retrieved by GetHostName()hostname should be the same name that appears in the Registry Hostname data value, along with the Domain data value, to create the complete fully-qualified domain name (FQDN) of the system. The FQDN includes the local hostname, along with the full domain name information.

GetHostByName()

The GetHostByName() method performs a DNS query for a specified hostname using the default DNS server configured on the system. The format of the method is as follows:
IPHostEntry GetHostByName(string hostname)
The IPHostEntry that is returned by GetHostByName() is itself an interesting object. It associates a DNS hostname with an array of alias names and IP addresses. It contains three properties:
  • AddressList: An array of IPAddress objects, one for each assigned IP address
  • Aliases: An array of string objects, one for each alias
  • HostName: A string object for the hostname
The AddressList and Aliases objects must be separated into their individual array elements in order to retrieve the information stored. This is often done using the foreach function in C#. 

The FindDNSServer.cs program

using System;
using Microsoft.Win32;
class FindDNSServers
{
  public static void Main()
  {
   RegistryKey start = Registry.LocalMachine;
   string DNSservers = @"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters";
   RegistryKey DNSserverKey = start.OpenSubKey(DNSservers);
   if (DNSserverKey == null)
   {
     Console.WriteLine("Unable to open DNS servers key");
     return;
   }
   string serverlist = (string)DNSserverKey.GetValue("NameServer");
   Console.WriteLine("DNS Servers: {0}", serverlist);
   DNSserverKey.Close();
   start.Close();
   char[] token = new char[1];
   token[0] = ' ';
   string[] servers = serverlist.Split(token);
   foreach(string server in servers)
   {
     Console.WriteLine("DNS server: {0}", server);
   }
  }
}

Using C# to Investigate the DNS Configuration

When your C# application is running on a customer’s system, you have no guarantee that there are any DNS servers configured. You can find out what (if any) DNS servers are configured by using the .NET Registry class methods to examine the DNS Registry values.
Fortunately, all Windows platforms store the DNS server information in the same place:
HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
This key stores all the DNS parameters from the Internet Protocol Properties window as separate data values. Table describes some of the values that are stored under this key.
Table 4.4: Registry Data Values for DNS Servers
Data Value
Description
DatabasePath
The location of the host’s file
Domain
The name of the system’s domain
Hostname
The name of the system’s DNS host
NameServer
The list of DNS servers
SearchList
A list of DNS domains to append to the end of hostnames in DNS name searches
The value of most interest here is NameServer. This should contain a single string value representing all the configured DNS servers, separated by spaces. The primary DNS server will be listed first, followed by the alternate servers.
Note 
If the workstation uses DHCP to dynamically assign an IP address, it may also dynamically assign DNS server addresses. These values are stored with the DHCP information of the connection, in place of the normal IP parameters section shown for this discussion.
You can create a C# program to query this Registry value using the .NET Registry class.

Domain Name System/Service (DNS) and C#

Overview

IP addresses and network programs go hand in hand. When writing socket programs, you must indicate the IP address of either the local host for server applications, or a remote host for client applications. Sometimes this is not an easy thing to do—equating IP addresses and hostnames can be complicated. If all we ever needed were IP addresses, life would be a lot simpler for the network programmer.
In the real world, however, everywhere you look—books, magazines, websites, television advertisements, and all the rest—you see hostnames thrown at you. The Internet has made the hostname a common household item. Because of this, almost all network programs must allow customers to enter hostnames as well as IP addresses, and it is up to the network programmer to ensure that the program can find the IP address that is properly associated with the hostname. The primary control mechanism for accomplishing this is the Domain Name System (DNS), which is used to control hostnames and provide information to hosts wanting to find the IP address of another hostname.