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.

Finding IP Address Information

One of the biggest challenges of network programming is dealing with network configurations of individual workstations and servers. When sending data across the network, you often need to determine the IP network information for the system running your program. The Windows OS family offers many ways to determine IP configuration information, both manually and from within a program. This section demonstrates a few of the ways that you can use to determine IP configuration information both manually and within your C# programs.

Using ipconfig

The ipconfig program displays IP network information for each active network interface on the system. The default form of ipconfig displays basic information for each network device:
C:\>ipconfig
Windows NT IP Configuration
Ethernet adapter El90x1:
    IP Address. . . . . . . . . : 192.168.1.6
    Subnet Mask . . . . . . . . : 255.255.255.0
    Default Gateway . . . . . . : 192.168.1.1
PPP adapter NdisWan5:
    IP Address. . . . . . . . . : 0.0.0.0
    Subnet Mask . . . . . . . . : 0.0.0.0
    Default Gateway . . . . . . :
C:\>
Here, the ipconfig program found two network interfaces configured on the workstation. The first interface is an Ethernet card configured for a LAN with a static IP address assigned to the workstation. The second device is a PPP connection configured to use a modem in the workstation. Because the PPP connection obtains its IP information dynamically when the PPP session starts, the values set by default in the workstation are zeroed. When the PPP connection is enabled, the assigned IP information is displayed.
To obtain more detailed information about a device, use the /all switch for the ipconfig command, as shown here:
C:\>ipconfig /all
Windows NT IP Configuration
    Host Name . . . . . . . . . : shadrach.blum.lan
    DNS Servers . . . . . . . . : 192.168.1.1
                   192.168.1.2
                   192.168.1.3
    Node Type . . . . . . . . . : Broadcast
    NetBIOS Scope ID. . . . . . :
    IP Routing Enabled. . . . . : No
    WINS Proxy Enabled. . . . . : No
    NetBIOS Resolution Uses DNS : No
Ethernet adapter El90x1:
    Description . . . . . . . . : 3Com EtherLink PCI
    Physical Address. . . . . . : 00-50-DA-10-78-67
    DHCP Enabled. . . . . . . . : No
    IP Address. . . . . . . . . : 192.168.1.6
    Subnet Mask . . . . . . . . : 255.255.255.0
    Default Gateway . . . . . . : 192.168.1.1
PPP adapter NdisWan5:
Description . . . . . . . . : NdisWan Adapter
    Physical Address. . . . . . : 00-00-00-00-00-00
    DHCP Enabled. . . . . . . . : No
    IP Address. . . . . . . . . : 0.0.0.0
    Subnet Mask . . . . . . . . : 0.0.0.0
    Default Gateway . . . . . . :
C:\>

Analyzing Network Packets

The ability to watch an IP session and decode its meaning is a crucial skill for a network programmer. To fully understand the concepts behind network programming, you must first understand the IP protocol and how it moves data among network devices. Getting familiar with this information could save you countless hours of troubleshooting network programs that aren’t behaving the way you think they should.
The network packets that you capture contain several layers of information to help the data get transported between the two network devices. Each layer of information contains bytes arranged in a predetermined order, specifying parameters specific for the protocol layer. Most packets that you will use in IP network programming will contain three separate protocol layers of information, along with the actual data being transmitted between network devices. Figure illustrates the protocol hierarchy used for IP packets, as discussed in the sections that follow.
 
Figure: Network protocol layers in packets

Watching Network Traffic

One of the biggest difficulties for network programmers is not being able to see exactly what is happening on the network. Often you think you have created the perfect client/server application, spending hours working out the mechanics of sending and receiving application data among machines, only to find out that somewhere along the network your data is not getting through. A network analyzer can be the network programmer’s best friend in finding out what is happening “on the wire.” Programming errors can often be detected by watching application data pass from one device to another.
This section shows how to install a simple public-domain network analyzer on your Windows workstation or server to help you debug network programming problems.
Note 
 If you are developing C# programs on a Windows NT 4 or 2000 server, you already have a network analyzer program built into your system: netmon. This program offers a way to capture and view network packets that enter and leave the server. Unfortunately, this program is not available on other Windows platforms. Therefore, to be consistent for all C# development platforms, this chapter discusses implementation of a public-domain network analyzer that operates on all Windows platforms on which the .NET Framework runs. This analyzer is the WinPcap driver and its associated tools, WinDump and Analyzer.

IP Programming Basics

Overview

The Internet Protocol (IP) is at the core of network programming. IP is the vehicle that transports data between systems, whether within a local area network (LAN) environment or a wide area network (WAN) environment. Though there are other network protocols available to the Windows network programmer, IP provides the most robust technique for sending data between network devices, especially if they are located across the Internet.
Programming using IP is often a complicated process. There are many factors to consider concerning how data is sent on the network: the number of client and server devices, the type of network, network congestion, and error conditions on the network. Because all these elements affect the transportation of your data from one device to another, understanding their impact is crucial to your success in network programming. Often what you think is happening in your programs is not happening on the network. This chapter describes a method of watching IP traffic on the network to help you debug your network programs.
This chapter also examines the parts of IP communications necessary to your understanding of network communications, along with the inner workings of the two most popular protocols that use IP: the Transmission Control Protocol (TCP) and the User Datagram Protocol (UDP). Finally, one of the most confusing network issues is IP network addressing. This chapter finishes up with a helpful look at Microsoft Windows systems’ handling of IP addresses, and how you can programmatically determine the IP address configuration of the system on which your program is running.

Monday, November 22, 2010

Using C# to Query WMI

Using WMI

In addition to the Registry, there’s another source available to you for obtaining IP network information from Windows systems. The Windows Management Instrumentation (WMI) is the Microsoft implementation of Web-Based Enterprise Management (WBEM), which is a standard for accessing system information in a network environment, developed by the Distributed Management Task Force, Inc. (DMTF). Since Windows 2000, Microsoft has included in the OS a database that contains information regarding system hardware and software, as well as current hardware status. The C# language can query the database to determine the status of managed hardware and software components, including network devices.

IP Info in WMI

The WMI Win32 NetworkAdapterConfiguration table within WMI contains information related to the network devices installed on the system. The result of the table query is a collection of information for each network interface. Each network interface represents one record in the returned collection. The IP information for the network interface appears as separate fields within the record.

Using C# to Query WMI

The .NET System.Management namespace contains classes used for querying the WMI databases. You can create a C# program to query WMI for each network interface installed on the system and then display the IP information returned. The steps to use to query the WMI database from a C# program are as follows:
  1. Create a ManagementObjectSearcher object that contains a SQL Select statement for the database table.
  2. Create a ManagementObjectCollection object to obtain the result set from executing the SQL query.
  3. In a foreach loop, assign a new ManagementObject for each object in the Management-ObjectCollection.
  4. Assign the desired data fields to regular type variables.
Listing 2.3 shows the WMICardGrab.cs program, which uses the C# WMI classes to obtain the network interface IP information.
Listing 2.3: WMICardGrab.cs program
Start example
using System;
using System.Management;
class WMICardGrab
{
  public static void Main ()
  {
    ManagementObjectSearcher query = new
    ManagementObjectSearcher("SELECT * FROM Â
     Win32_NetworkAdapterConfiguration WHERE IPEnabled = 'TRUE'");
    ManagementObjectCollection queryCollection = query.Get();
    foreach( ManagementObject mo in queryCollection )
    {
      string[] addresses = (string[])mo["IPAddress"];
      string[] subnets = (string[])mo["IPSubnet"];
      string[] defaultgateways =
           (string[])mo["DefaultIPGateway"];
      Console.WriteLine("Network Card: {0}",
             mo["Description"]);
      Console.WriteLine("  MAC Address: {0}",
             mo["MACAddress"]);
      foreach(string ipaddress in addresses)
      {
        Console.WriteLine("  IP Address: {0}",
             ipaddress);
      }
      foreach(string subnet in subnets)
      {
        Console.WriteLine("  Subnet Mask: {0}", subnet);
      }
      foreach(string defaultgateway in defaultgateways)
      {
        Console.WriteLine("  Gateway: {0}",
             defaultgateway);
      }
    }
  }
}
End example
The C# WMI class ManagementObjectSearcher defines the SQL query that will be performed against the WMI database. You can use the IPEnabled field to your advantage, filtering out any network devices that do not have IP configured:
ManagementObjectSearcher query = new
    ManagementObjectSearcher("SELECT * FROM Â
    Win32_NetworkAdapterConfiguration WHERE IPEnabled = 'TRUE'");
ManagementObjectCollection queryCollection = query.Get();
The result of the query is stored in a ManagementObjectCollection. Each collection item represents one record in the result set, and each record represents one network interface. The handy foreach C# function can be used to iterate through the retrieved recordset collection, examining each record individually and assigning it to a ManagementObject object. Fields within the record are referenced using their proper field name:
string[] addresses = (string[])mo["IPAddress"];
string[] subnets = (string[])mo["IPSubnet"];
string[] defaultgateways = (string[])mo["DefaultIPGateway"];
Similar to the Registry version, the IPAddress, IPSubnet, and DefaultIPGateway values are arrays that can contain more than one value. To accommodate this, you must assign the result to a string array, and step through the string array, again with a foreach statement.
The IP information retrieved from the WMICardGrab program should be the same as from the Registry version:
C:\>WMICardGrab
Network Card: D-Link DE660 PCMCIA LAN adapter
  MAC Address: 00:80:C8:BC:CE:C3
  IP Address: 192.168.1.6
  Subnet Mask: 255.255.255.0
  Gateway: 192.168.1.1
C:\>

Using DNS

The last way to determine system IP information is to utilize the C# DNS (Domain Name System) classes. 
The C# System.Net namespace contains the Dns class, which comprises several methods that allow you to obtain DNS information about hosts. The GetHostName() method retrieves the hostname of the local system. The GetHostByName() method attempts to find the IP address of a hostname. You can combine these two functions to find the IP address of the local system. 
Listing 2.4: DNSName.cs program
Start example
using System;
using System.Net;
class DNSName
{
  public static void Main ()
  {
   string hostName = Dns.GetHostName();
   Console.WriteLine("Local hostname: {0}", hostName);
   IPHostEntry myself = Dns.GetHostByName(hostName);
   foreach (IPAddress address in myself.AddressList)
   {
   Console.WriteLine("IP Address: {0}", address.ToString());
   }
  }
}
Again, similar to the Registry and WMI programs, you must take into account the possibility of the local system having more than one IP address assigned to it. The AddressList property of the IPHostEntry class is an array of type IPAddress. You can use the foreach function to extract each of the IP addresses in the array. The output of this program is very simple:
C:\>DNSName
Local hostname: abednego
IP Address: 192.168.1.6
C:\>
This is a very common method to use to get the local system IP address for determining the local IP address to use for creating server network connections. 

Using C# to Search the Registry

Using C# to Search the Registry

Once you have determined where to find the network information in the Registry of your target system, you can create C# code to search for it and display the information to the user (or use it in your program). In this section, we’ll examine a C# program to query the system Registry for IP information.
The .NET Framework provides a set of classes that help you query and manipulate Registry entries. The .NET Registry classes are contained in two separate namespaces:
Microsoft.Win32.Registry The Microsoft.Win32.Registry namespace contains all the base classes needed to access the base Registry key names: Current_User, Local_Machine, Classes_Root, Current_Config, Dyn_Data, and Users. You must use one of the base Registry key names to build your specific Registry subkey.
Microsoft.Win32.RegistryKey The Microsoft.Win32.RegistryKey namespace contains the classes and methods necessary to query and modify Registry keys and data. The OpenSubKey() method allows you to open a subkey of a known key and access any data values contained in the subkey. Once you have the appropriate subkey, you can use the GetValue() method to get the data values assigned to the subkey.
Listing 2.2 presents the CardGrab.cs program, which will find the network devices installed on a Windows NT, 2000, or XP system using the system Registry, and display the IP information for each device.
Listing 2.2: CardGrab.cs program
Start example
using System;
using Microsoft.Win32;
class CardGrab
{
  public static void Main ()
  {
  RegistryKey start = Registry.LocalMachine;
  RegistryKey cardServiceName, networkKey;
  string networkcardKey = "SOFTWARE\\Microsoft\\ Â
      Windows NT\\CurrentVersion\\NetworkCards";
  string serviceKey =
      "SYSTEM\\CurrentControlSet\\Services\\";
  string networkcardKeyName, deviceName;
  string deviceServiceName, serviceName;
  RegistryKey serviceNames =
            start.OpenSubKey(networkcardKey);
  if (serviceNames == null)
  {
    Console.WriteLine("Bad registry key");
    return;
  }
  string[] networkCards = serviceNames.GetSubKeyNames();
  serviceNames.Close();
  foreach(string keyName in networkCards)
  {
    networkcardKeyName = networkcardKey + "\\" + keyName;
    cardServiceName = start.OpenSubKey(networkcardKeyName);
    if (cardServiceName == null)
    {
     Console.WriteLine("Bad registry key: {0}",
         networkcardKeyName);
     return;
    }
    deviceServiceName =
       (string)cardServiceName.GetValue("ServiceName");
          deviceName =
           (string)cardServiceName.GetValue("Description");
    Console.WriteLine("\nNetwork card: {0}", deviceName);
     
    serviceName = serviceKey + deviceServiceName +
      "\\Parameters\\Tcpip";
    networkKey = start.OpenSubKey(serviceName);
    if (networkKey == null)
    {
     Console.WriteLine("  No IP configuration set");
    } else
    {
      string[] ipaddresses =
        (string[])networkKey.GetValue("IPAddress");
      string[] defaultGateways =
        (string[])networkKey.GetValue("DefaultGateway");
      string[] subnetmasks =
        (string[])networkKey.GetValue("SubnetMask");
      foreach(string ipaddress in ipaddresses)
      {
        Console.WriteLine("  IP Address: {0}",ipaddress);
      }
      foreach(string subnetmask in subnetmasks)
      {
        Console.WriteLine("  Subnet Mask: {0}",
         subnetmask);
      }
      foreach(string defaultGateway in defaultGateways)
      {
        Console.WriteLine("  Gateway: {0}",
              defaultGateway);
      }
      networkKey.Close();
    }
  }
  start.Close();
  }
}
End example
You must define a root key to begin the key search. This is done using the Registry class:
RegistryKey start = Registry.LocalMachine;
This creates a Registry key object start and sets it to the root class HKLM_LOCAL_MACHINE.
Next, you drill down and set a key object to the pertinent subkey where the network device information is located:
string networkcardKey = "SOFTWARE\\Microsoft\\ Â
      Windows NT\\CurrentVersion\\NetworkCards";
RegistryKey serviceNames =
            start.OpenSubKey(networkcardKey);
Now the key object serviceNames points to the location of the installed network device subkeys.
Next you use the GetSubKeyNames() method to iterate through each of the network device subkey names. Because the same key name is used for the service keys, you can add that value to the known service key location and open the subkey using the OpenSubKey() method, again referenced from the root key:
serviceName = serviceKey + deviceServiceName + "\\Parameters\\Tcpip";
  networkKey = start.OpenSubKey(serviceName);
Once each subkey is opened, the IP information is retrieved from the service key using the GetValue() method of the key object. Because each IP information data entry can have multiple values, you must assign the result to a string array and display the complete array using the foreach function:
string[] ipaddresses =
        (string[])networkKey.GetValue("IPAddress");
foreach(string ipaddress in ipaddresses)
{
  Console.WriteLine("  IP Address: {0}",ipaddress);
}
A sample output of the CardGrab program should look like this:
C:\>CardGrab
Network card: D-Link DE660 PCMCIA LAN adapter
  IP Address: 192.168.1.6
  Subnet Mask: 255.255.255.0
  Gateway: 192.168.1.1
C:\>
You can use a similar technique to find the IP information for Windows 98 or Me devices. In fact, that technique is much simpler because you only have to search in one location for the IP information.

C# Namespaces

With all of the classes provided in the .NET Framework, it’s easy to get confused about which classes perform which functions and the methods that should be used from particular classes. To help simplify things, Microsoft uses namespaces in classifying .NET Framework classes.

What Are Namespaces?

C# application consists of one or more classes. Each class defines an object that can contain data and methods to manipulate the data. At least one class in each application must contain a program interface method called Main(). The Main() method lets the C# compiler know where to begin execution of the program. Other classes can be defined within the program (such as the DataClass), or can even be shared with other programs.
       C# namespaces are used to identify a higher-level hierarchy of class names, allowing you to group similar classes together within a single namespace. The namespace is defined in the source code file before the class definition, using the namespace directive:
namespace Test1;
class testProgram
{
}
namespace Test2;
class testProgram
{
}
For programs that do not declare a namespace (such as the SampleClass program) the defined classes become part of a global namespace. These classes are globally available to any application in the CLR.
Each namespace uniquely identifies the programs within it. Notice that both of the sample namespaces just shown contain a class called testProgram; most likely they perform separate functions. If your program needs to use one or both of the testProgram classes, you must specify which class you mean to use by referencing the namespace.

.NET Framework Namespaces
The .NET Framework uses namespaces to help categorize library classes used in the CLR. This helps programmers determine the location of various classes and how to define them in their programs.
Many .NET Framework namespaces make up the core CLR classes. Table 1.3 lists some of the common namespaces you will encounter in your C# network applications.
Table 1.3: .NET Framework Class Namespaces
Namespace
Description of Classes
Microsoft.Win32
Handles events raised by the OS and Registry handling classes
System
Base .NET classes that define commonly used data types and data conversions
System.Collections
Defines lists, queues, bit arrays, and string collections
System.Data
Defines the ADO.NET database structure
System.Data.OleDb
Encapsulates the OLE DB .NET database structure
System.Drawing
Provides access to basic graphics functionality
System.IO
Allows reading and writing on data streams and files
System.Management
Provides access to the Windows Management Instrumentation (WMI) infrastructure
System.Net
Provides access to the Windows network functions
System.Net.Sockets
Provides access to the Windows sockets (Winsock) interface
System.Runtime.Remoting
Provides access to the Windows distributed computing platform
System.Security
Provides access to the CLR security permissions system
System.Text
Represents ACSII, Unicode, UTF-7, and UTF-8 character encodings
System.Threading
Enables multi-threading programming
System.Timers
Allows you to raise an event on a specified interval
System.Web
Enables browser and web server functionality
System.Web.Mail
Enables sending mail messages
System.Windows.Forms
Creates Windows-based application using the standard Windows graphical interface
System.XML
Provides support for processing XML documents

Using Namespaces in Programs

An easier way is to declare the namespace with the C# using directive at the beginning of the program. Any classes contained within a namespace declared with using do not have to be referenced by their namespace name:
using System;
Console.WriteLine("The result is {0}", sample.addem());
The C# compiler searches all declared namespaces for the Console class and automatically references the proper namespace.

C Sharp basics: Using Multiple Source Files

The SampleClass.cs example program defined two separate classes in one source code file. This was easy to do for a small example, but larger programs can get confusing when you’re combining classes into one source code file. Often it is best to create a separate source code file for each class used in the application. This allows better code management, especially when several people are working on an application that contains hundreds of classes. For example, two separate files could be created:
  • DataClass.cs for the DataClass class code
  • SampleClass2.cs for just the SampleClass class code
There are a few things to be careful of when you separate classes out into discrete source code files. First, you must ensure that the C# compiler can find them at compile time. The easiest way to do this is to include all related source code files on the command line, as follows:
C:\>csc SampleClass2.cs DataClass.cs
Be careful when you do this, however, because the source code file listed first will be the default .exe filename. If you want to change the .exe filename, you can use the /out: command line switch:
C:\>csc /out:SampleClass2.exe DataClass.cs SampleClass2.cs
Another issue is the importance of telling the compiler where the program execution starts. If only one class has a Main() section defined, this will work fine. However, sometimes different classes can use methods from other classes, but both classes may contain a Main() method. This would confuse the compiler, as it would not know from which Main() method to start to run the program.
A command-line switch for the csc.exe program solves this problem. The /main:switch defines the class that contains the Main() method you want to use:
C:\>csc /main:SampleClass SampleClass2.cs DataClass.cs
Notice that you must specify the class that the Main() method is in, not the source code filename.

C# Programming Basics

Creating C# Programs

If you are using one of the Microsoft Visual products to develop your programs (Visual Studio .NET or Visual C# .NET), you have a complete program editing environment, including help files, graphical wizards, and command completion wizards. If you are using the .NET Framework SDK package, you are on your own for producing and compiling your C# code. Although this SDK’s features pale in comparison to the fancy Visual packages, it is nonetheless just as valid a way to produce C# applications.
The first step to working with C# programs in the .NET Framework development environment is to associate the C# source code filename extension with a text editor. This will make editing programs much easier; you can just double-click a program from within the Windows Explorer program to begin editing. The type of editor you select is important. Choose one that allows you to save your source code files in text mode rather than a Microsoft Word .doc file or other word processing document, because the C# compiler must be able to interpret each line of code. If you do select a word processing package to edit your C# programs, make sure that you save all of the files in text format.
After you select an editor, associate the .CS file type to the editor application within the Windows Explorer: right-click a C# program, select the Open With option, and select the appropriate application from the list.
If you are new to C#, you may want to practice compiling and debugging C# programs. To do that, you must first have a sample program to work with. Listing 1.1 shows a simple program that demonstrates some basic C# programming principles.
Listing 1.1: SampleClass.cs program
Start example
class DataClass
{
  private int a;
  private int b;
  public DataClass(int x, int y)
  {
    a = x;
    b = y;
  }
  public int addem()
  {
    return a + b;
  }
}
class SampleClass
{
  static int sampleX;
  static int sampleY;
  public SampleClass()
  {
    DataClass sample = new DataClass(sampleX, sampleY);
    System.Console.WriteLine("The result is: {0}", sample.addem());
  }
  public static void Main(string[] argv)
  {
  if (argv.Length != 2)
    {
      System.Console.WriteLine(" Usage: SampleClass x y");
      return;
    }
    sampleX = System.Convert.ToInt16(argv[0]);
    sampleY = System.Convert.ToInt16(argv[1]);
    SampleClass starthere = new SampleClass();
  }
}
--------------------------------------------------------------------------
The sample program contains two separate C# classes, DataClass and SampleClass. DataClass declares two private integers (that is, they are
only accessible from the DataClass class), a
constructor for the class, and a method that manipulates the data. The DataClass constructor defines what happens when DataClass is instantiated from a program:
public DataClass(int x, int y)
{ a = x; b = y;
}
The default constructor requires two integers. The two integers
are assigned to the internal private variables a and b
defined in the class. The one method that is defined, addem, returns an integer value that is the addition of the
two private variables:
public int addem()
{
return a + b; }
Note 
Once DataClass is defined in the program, other classes in the program can use it. In C#, unlike C++, you can use classes before they are defined without first declaring them. The SampleClass code could just as easily have been defined first, before the DataClass definition. The C# compiler will realize that the required class is located later in the program. You can even declare classes in separate files, as long as you include them on the command line when compiling. The compiler will only complain if declared classes are never found in any of the program files listed on the command line.
SampleClass contains two static integer
variables, a constructor, and a Main() method, which
instructs the C# compiler where to start execution of the program. The Main() method first checks to ensure that two command-line
parameters have been entered, converts them to integer values, and assigns them
to the two integer variables defined. It then creates an instance of SampleClass using the statement
SampleClass starthere = new SampleClass();
This forces the CLR to execute the SampleClass constructor to create a new instance of the
class.
The SampleClass constructor code creates
an instance of DataClass, passing the two integers to
the DataClass class constructor. The addem() method is called from the instantiated SampleClass variable and returns the result of the addition
method. The following line is used to display the result of the addem() method to the console screen:
System.Console.WriteLine("The result is: {0}", sample.addem());
The symbol {0} is used as a placement
value to represent a variable listed after the text string, in this case
replaced with the return value of the sample.addem()
method. You can add additional variables by continuing the placement numbers
({1}, {2}, and so on). Each additional variable is added to the variable list
separated by commas.
After typing the program code, you must save the file using a
.CS extension, which identifies the file as a C# code
file. Once you save the file, you are ready to compile it.


Sunday, August 8, 2010

Object Oriented Programing Polymorphism

Introduction to Polymorphism

If class Rectangle is derived from class Quadrilateral (a four-sided shape), then a Rectangle is a more specific version of aQuadrilateral. Any operation (e.g., calculating the perimeter or the area) that can be performed on a Quadrilateral object can also be performed on a Rectangle object. These operations also can be performed on other Quadrilaterals, such as Squares, Parallelograms and TRapezoids.
The polymorphism occurs when an application invokes a method through a base class variableat execution time, the correct derived class version of the method is called, based on the type of the referenced object.
As another example, suppose we design a video game that manipulates objects of many different types, including objects of classes Martian, Venusian, Plutonian, SpaceShip and LaserBeam. Imagine that each class inherits from the common base class SpaceObject, which contains method Draw. Each derived class implements this method. A screen-manager application maintains a collection (e.g., a SpaceObject array) of references to objects of the various classes. To refresh the screen, the screen manager periodically sends each object the same messagenamely, Draw. However, each object responds in a unique way.
For example, a Martian object might draw itself in red with the appropriate number of antennae. A SpaceShip object might draw itself as a bright silver flying saucer. A LaserBeam object might draw itself as a bright red beam across the screen. Again, the same message (in this case, Draw) sent to a variety of objects has "many forms" of results.
A polymorphic screen manager might use polymorphism to facilitate adding new classes to a system with minimal modifications to the system's code. Suppose we want to add Mercurian objects to our video game. To do so, we must build a Mercurian class that extends SpaceObjectand provides its own Draw method implementation. When objects of class Mercurian appear in the SpaceObject collection, the screen manager code invokes method Draw, exactly as it does for every other object in the collection, regardless of its type. So the new Mercurian objects simply "plug right in" without any modification of the screen manager code by the programmer. Thus, without modifying the system (other than to build new classes and modify the code that creates new objects), programmers can use polymorphism to include additional types that might not have been envisioned when the system was created.

Operator Overloading

Manipulations of class objects are accomplished by sending messages (in the form of method calls) to the objects. This method-call notation is cumbersome for certain kinds of classes, especially mathematical classes. For these classes, it would be convenient to use C#'s rich set of built-in operators to specify object manipulations. In this section, we show how to enable these operators to work with class objectsvia a process called operator overloading.

Monday, June 7, 2010

Object Oriented Programing Classes

Class

We can declare a class using the keyword "class" ,which following syntax:

[access-modifier] keyword class class-name {class-body}
for example
public class addmethod {

//class-body
}


The syntax elements are as follows:

access-modifier The degree to which your class is available to the outside world.
it may be public, private, protected etc.

class-name The name you assign to your class.
"addmethod" is the name of our class

class-body The body of your class.

Classes are usually declared using the public access modifier, meaning that the class is available without restriction


public class Car
{


// declare the fields


public string make;
public string model;

public string color;

public int yearBuilt;

// define the methods
public void Start()
{
System.Console.WriteLine(model + " started");
}

public void Stop()
{
System.Console.WriteLine(model + " stopped");
}

}