Chapter 6: Introduction to System.Net


System.Net is the namespace in the Microsoft Windows .NET Framework that contains the core classes intended for building applications that communicate over a network. The types of functionality found in System.Net range from access to a raw socket to the ability to upload to and download from resources on the Internet. In addition to providing a language-independent, object-oriented way to access network resources, System.Net serves as the communication infrastructure for higher-level, distributed application programming models such as XML-based Web services and .NET Remoting.

Layers of System.Net

The System.Net classes can be divided into four layers, as depicted in Figure 6-1 and described in the following list.


Figure 6-1: The layers of System.Net
  • Basic network types and services Fundamental types that are used for working with Internet Protocol (IP) addresses or non-IP network addresses such as Internetwork Packet Exchange (IPX). This layer also includes classes for performing Domain Name System (DNS) resolution.

  • Socket-level APIs A set of managed classes for performing network communication over a socket, such as sending and receiving data between two hosts .

  • Application protocols Classes intended to be used both on the client and on the middle tier . These classes are for protocols layered on top of the socket APIs, such as the Hypertext Transfer Protocol (HTTP) and the File Transfer Protocol (FTP).

  • Protocol-independent request-response model These classes provide a pattern that is used by request-response protocols for resolving Uniform Resource Identifiers (URIs) without requiring the developer to write protocol-specific code.

In this section, we ll walk through each layer and introduce the most commonly used classes for each layer. The layers will be covered in-depth in the following chapters.

Basic Network Types and Services

Figure 6-2 contains the classes that make up the basic types and services included in System.Net . In the subsequent sections, we ll look briefly at each of the basic types and services that are made accessible through System.Net . Although this section introduces the key types, most of them are covered in- depth in the chapters that follow.


Figure 6-2: Basic types and services provided by System.Net

Using IP Addresses

The IPAddress type provides a class representation of an IP address. It includes methods that can be used to perform common operations on an IP address, such as parsing the address. The following code shows how you would parse an IP address.

C#
 staticvoidParseIPAddress(stringaddressString) { try { IPAddressaddress=IPAddress.Parse(addressString); Console.WriteLine(Theaddressis  +address.ToString() +  andisofthefamily  +address.AddressFamily.ToString()+ .); } catch(Exceptionex) { Console.WriteLine(Failureparsing  +addressString+ .  + ex.ToString()); } } 
Visual Basic .NET
 SubParseIPAddress(ByValaddressStringAsString) Try DimaddressAsIPAddress address=IPAddress.Parse(addressString) Console.WriteLine(Theaddressis  &address.ToString_ &  andisofthefamily  &_ address.AddressFamily.ToString+ .) CatchexAsException Console.WriteLine(Failureparsing &addressString&_  .  &ex.ToString) EndTry EndSub 

Note that if an invalid IP address is specified in this case, IPAddress will throw a FormatException that should be handled by the application. The IPAddress class should be used for validation any time your application receives an IP address as input from a user , a configuration file, or another source. IPAddress also provides the ability to determine whether a particular address is a member of the Internet Protocol version 6 (IPv6) or the Internet Protocol version 4 (IPv4) address family. Finally, IPAddress contains a number of helper methods and fields, such as IPAddress.Any , IPAddress.IPv6Any , and IPAddress.IsLoopback . The Any fields can be used to indicate that the application should bind to a port that listens on all network interfaces of that address family. The IsLoopback method can be useful when validating whether a local loopback address is being used. More information regarding IP addressing is found in Chapter 7.

Working with Different Address Families

The System.Net.EndPoint class provides developers with a way to access resources through System.Net over protocols that belong to different address families that have different semantics at the addressing level. This functionality is useful when you need to write an application that talks over a non-IP protocol, such as AppleTalk, IPX, or infrared. Because IP-based protocols are the most commonly used on today s networks, System.Net includes an IPEndPoint type in the .NET Framework. In the case of IPEndPoint , an end point is defined as an IP address and a port number. The .NET Compact Framework includes an IrDAEndPoint implementation of the EndPoint class that can be used for communicating with other nodes using infrared technologies. In the case of an IrDAEndPoint , an end point is defined as a device ID and a service name. Although most developers will simply work within the confines of the IP address family, this extensibility point is useful because the definition of an end point often varies from one address family to another.

Accessing Protected Resources

System.Net defines an ICredential interface and an associated NetworkCredential class that provide a means of specifying network credentials, such as a user name and a password in cases where network authentication is required when accessing a resource. These classes are mainly used in the context of the HTTP application protocol classes. However, in an upcoming release of the .NET Framework, their use is likely to be expanded to include other socket-level authentication scenarios as well. The following code demonstrates how you can use the NetworkCredential class to authenticate with a remote resource.

C#
 staticvoidRequestProtectedResource(stringresource) { Console.WriteLine(Pleaseenteryourusername.); stringuserName=Console.ReadLine(); Console.WriteLine(Pleaseenteryourpassword.); stringpassword=Console.ReadLine(); WebClientclient=newWebClient(); client.Credentials=newNetworkCredential(userName,password); client.DownloadFile(resource, page.htm); } 
Visual Basic .NET
 SubRequestProtectedResource(ByValresourceAsString) Console.WriteLine(Pleaseenteryourusername.) DimuserNameAsString userName=Console.ReadLine() Console.WriteLine(Pleaseenteryourpassword.) DimpasswordAsString password=Console.ReadLine() DimclientAsNewWebClient client.Credentials=NewNetworkCredential(userName,password) client.DownloadFile(resource, page.htm) EndSub 
Note  

Notice that in this code the credentials are obtained by prompting the user to enter them on the command line. System.Net also provides a way of using the default credentials of the account under which the application is running. You do so by setting the Credentials property on a class equal to CredentialCache.DefaultCredentials . Whenever possible, developers should use default credentials instead of prompting the user or reading credentials from some other source because default credentials are obtained through the security systems integrated into the underlying operating system.

Accessing DNS

DNS can be used to represent nodes on the network with human-readable names rather than IP addresses. For example, imagine trying to remember a string of characters such as www.contoso.com instead of a series of numbers such as 207.168.24.30 . One feature provided by DNS is the ability to have multiple IP addresses assigned to one host name. You can even have different IP address types (for example, IPv4 and IPv6) assigned to the same host. It s often useful to be able to resolve a name to the list of IP addresses associated with that name.

Access to DNS is enabled and controlled in System.Net through the Dns , DnsPermission , and IPHostEntry classes. DNS is covered in more detail in Chapter 7. The following example shows the basic steps involved in resolving a name and outputting the corresponding IP addresses to the console using System.Net .

C#
 staticvoidResolveName(stringname) { try { IPHostEntryhostInfo=Dns.Resolve(name); foreach(IPAddressaddressinhostInfo.AddressList) Console.WriteLine(address.ToString()); } catch(Exceptionex) { Console.WriteLine(ex.ToString()); } } 
Visual Basic .NET
 SubResolveName(ByValnameAsString) Try DimhostInfoAsIPHostEntry hostInfo=Dns.Resolve(name) DimaddressAsIPAddress ForEachaddressInhostInfo.AddressList Console.WriteLine(address.ToString) Nextaddress CatchexAsException Console.WriteLine(ex.ToString) EndTry EndSub 

Using the Socket-Level Classes

The socket-level classes in System.Net enable fine-grained control over the way data is read from and written to the network. These classes include access to sockets, a stream pattern for network I/O, and some helper classes that simplify a number of the most common tasks that are desirable when working with this level of the network. Figure 6-3 displays the groups of classes that make up the socket-level APIs for System.Net .


Figure 6-3: Socket-level classes in System.Net

Socket Classes

The System.Net.Sockets namespace contains a class-based representation of the Windows Sockets model commonly known as Winsock. These classes are particularly focused on a subset of the Winsock model that deals with IP-based protocols such as User Datagram Protocol (UDP) and Transmission Control Protocol (TCP). These classes can be extended to enable other protocols such as NetBIOS and Infrared. The key classes to be aware of at this level are Socket , SocketPermission , and SocketException . The Socket class provides the vast majority of the functionality needed to access the network and acts as the gatekeeper for the transition from managed .NET Framework code to the underlying native Win32 APIs. SocketException is used to represent most exceptions that occur within the Socket class. The SocketPermission class is used to control access to socket-level resources through code access security. These classes are described in more detail in Chapters 8 and 9. The following example demonstrates how to download a Web page using the socket-level classes.

C#
 staticvoidMain(string[]args) { //Validatetheinputvalues if(args.Length<2) { Console.WriteLine("ExpectedDownloadWebPage.exeserverNamepath"); Console.WriteLine("Example:DownloadWebPage.execontoso.com/"); return; } stringserver=args[0]; stringpath=args[1]; intport=80; IPHostEntryhost=null; IPEndPointremoteEndPoint=null; Socketclient=null; //Resolvetheservername try { host=Dns.GetHostByName(server); } catch(Exceptionex) { Console.WriteLine(ex.ToString()); return; } //AttempttoconnectoneachaddressreturnedfromDNS //Breakoutoncesuccessfullyconnected foreach(IPAddressaddressinhost.AddressList) { try { client=newSocket(address.AddressFamily,SocketType.Stream, ProtocolType.Tcp); remoteEndPoint=newIPEndPoint(address,port); client.Connect(remoteEndPoint); break; } catch(SocketExceptionex) { Console.WriteLine(ex.ToString()); } } //MakeRequestwillissuetheHTTPdownloadrequest //andwritetheserverresponsetotheconsole MakeRequest(client,path,server); client.Close(); } publicstaticvoidMakeRequest(Socketclient,stringpath,stringserver) { //FormattheHTTPGETrequeststring stringGet= "GET " +path+ " HTTP/1.0\r\nHost: " +server + "\r\nConnection:Close\r\n\r\n"; Byte[]ByteGet=Encoding.ASCII.GetBytes(Get); //SendtheGETrequesttotheconnectedserver client.Send(ByteGet); //Createabufferthatisusedtoreadtheresponse byte[]responseData=newbyte[1024]; //readtheresponseandsavetheASCIIdatainastring intbytesRead=client.Receive(responseData); StringBuilderresponseString=newStringBuilder(); while(bytesRead!=0) { responseString.Append(Encoding.ASCII.GetChars(responseData), 0,bytesRead); bytesRead=client.Receive(responseData); } //Displaytheresponsetotheconsole Console.WriteLine(responseString.ToString()); } 
Visual Basic .NET
 SubMain(ByValargsAsString()) Validatetheinputvalues Ifargs.Length<2Then Console.WriteLine("ExpectedDownloadWebPage.exeserverNamepath") Console.WriteLine("Example:DownloadWebPage.execontoso.com/") Return EndIf DimserverAsString=args(0) DimpathAsString=args(1) DimportAsInteger=80 DimhostAsIPHostEntry DimremoteEndPointAsIPEndPoint DimclientAsSocket Resolvetheservername Try host=Dns.GetHostByName(server) CatchexAsException Console.WriteLine(ex.ToString()) Return EndTry AttempttoconnectoneachaddressreturnedfromDNS Exitoutoncesuccessfullyconnected ForEachaddressAsIPAddressInhost.AddressList Try client=NewSocket(address.AddressFamily, SocketType.Stream,ProtocolType.Tcp) remoteEndPoint=NewIPEndPoint(address,port) client.Connect(remoteEndPoint) ExitFor CatchexAsException Console.WriteLine(ex.ToString()) EndTry Next MakeRequestwillissuetheHTTPdownloadrequest andwritetheserverresponsetotheconsole MakeRequest(client,path,server) client.Close() EndSub SubMakeRequest(ByValclientAsSocket,ByValpathAsString, ByValserverAsString) FormattheHTTPGETrequeststring DimgetStringAsString= "GET " +path+ " HTTP/1.0" +ControlChars.CrLf getString+= "Host: " +server+ControlChars.CrLf+ "Connection:Close" getString+=ControlChars.CrLf+ControlChars.CrLf DimByteGetAsByte()=Encoding.ASCII.GetBytes(getString) SendtheGETrequesttotheconnectedserver client.Send(ByteGet) Createabufferthatisusedtoreadtheresponse DimresponseData()AsByte=NewByte(1024){} ReadtheresponseandsavetheASCIIdatainastring DimbytesReadAsInteger=client.Receive(responseData) DimresponseStringAsStringBuilder=NewStringBuilder WhilebytesRead>0 responseString.Append(Encoding.ASCII.GetChars(responseData), 0,bytesRead) bytesRead=client.Receive(responseData) EndWhile Displaytheresponsetotheconsole Console.WriteLine(responseString.ToString()) EndSub 

You ll notice that the sample for downloading a Web page using sockets is much longer than the code it would take to do the same thing using a higher layer in System.Net , such as WebRequest or WebClient . This additional code is the tradeoff that s often made when you decide to program at the socket level. Your application will have much greater control over the protocol that s emitted , but it does so at the cost of additional code.

Reading and Writing with NetworkStream

Although NetworkStream isn t a large class, it s extremely useful because it provides a stream-based model for reading and writing data over a network. NetworkStream implements the standard methods and properties that you ll find on the base System.IO.Stream pattern, as discussed in Chapter 2. You should consider a couple of interesting elements that are specific to this implementation when working with NetworkStream . First, a NetworkStream instance can be obtained either by constructing one from a socket or by getting one from another class such as one of the socket-level helper classes described in the next section. Second, because NetworkStream is based on a TCP connection and does not buffer data, it s not seekable.

Note  

You can t set the Position property to seek a particular point in the stream. You should be aware of this limitation if you rely on other classes that use the Stream type and expect this functionality from the stream.

Using the Socket-Level Helper Classes

The socket-level helper classes include TcpClient , TcpListener , and UdpClient . These classes simplify the most common tasks that an application might perform using the TCP and UDP protocols. The TcpClient class is focused on the scenario of connecting to a remote host and getting a stream that can be used to read and write data. The TcpListener class is the inverse of TcpClient . It provides methods for accepting an incoming socket connection and accessing a stream that s created on top of that connection. The UdpClient class contains methods for sending and receiving data over UDP, including JoinMulticastGroup and DropMulticastGroup for IP multicasting data.

Because the UDP protocol is connectionless, no model is provided for creating a NetworkStream on top of it. Without the ability to create a stream, there s little value to having a listener correspondent to the UdpClient class because the UdpClient.Receive method takes care of receiving data from a remote host.

Note  

Because the socket-level helper classes do not include asynchronous methods, applications designed for high-load scenarios should use the Socket class instead.

Application Protocols

The application protocols level contains classes designed for resolving specific protocols. Resources that can be resolved using these protocols are most often represented by a URI. In version 1.1 of the .NET Framework, the supported schemes include HTTP, HTTPS, and FILE. In an upcoming release of the .NET Framework, this layer will be enhanced to include FTP protocol support as well. Each of these protocols implements the general request-response pattern that will be described in the next section. Figure 6-4 provides a graphical representation of the key application protocol classes in version 1.1 of System.Net .


Figure 6-4: Application protocol classes in version 1.1 of System.Net

Protocol Support

The HTTP protocol is supported primarily by the HttpWebRequest and HttpWebResponse classes in System.Net . These classes provide a complete implementation of the HTTP 1.1 and 1 protocols. The feature set includes support for all of the HTTP verbs defined in RFC 2616 as well as custom commands, HTTP pipelining, and chunked uploading and downloading of content. HttpWebRequest and HttpWebResponse have been designed to work well under situations that require high load and scale. They re also suitable for use both in client application scenarios and n-tier server scenarios. The HTTP support in System.Net is described in more detail in Chapter 10. The following example demonstrates how to download a file using the HTTP classes.

C#
 staticvoidMain() { try { //Createtherequestobject HttpWebRequestrequest= (HttpWebRequest)WebRequest.Create("http://www.contoso.com/file.htm"); //Optionally,youcansetHTTP-specificelementson //therequest,suchastheUser-Agentheader request.UserAgent= "TestClientversion1.0"; //Issuetherequest HttpWebResponseresponse=(HttpWebResponse)request.GetResponse(); //Readthecontent StreamReaderreader=newStreamReader(response.GetResponseStream(), Encoding.ASCII); stringcontent=reader.ReadToEnd(); //Displaythecontenttotheconsole Console.WriteLine(content); //Closetheresponse response.Close(); } catch(WebExceptionwex) { Console.WriteLine(wex.ToString()); //Checkthestatustoseeiftheremightbearesponseobject if(wex.Status==WebExceptionStatus.ProtocolError) { HttpWebResponseresponse=(HttpWebResponse)wex.Response; Console.WriteLine(); Console.WriteLine("Theprotocolerrorreturnedwas" + response.StatusCode.ToString()+ " 


Network Programming for the Microsoft. NET Framework
Network Programming for the MicrosoftВ® .NET Framework (Pro-Developer)
ISBN: 073561959X
EAN: 2147483647
Year: 2003
Pages: 121

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net