Windows Forms: Windows Forms, contained in the System.Windows.Forms namespace, is a broad set of classes that enable rapid development of rich client applications. Using Windows Forms in conjunction with the networking technologies in the .NET Framework, you can create smart end-user applications that interact with other sources of information over the network and present them to the user. An e-mail client, the browser, and music/video players are all examples of rich client applications that use the network. The following sample demonstrates a Windows Forms application that’s used to take a URL from the user, resolve it, and display the resulting HTML in a text box, as shown in Figure 1-3.
Figure 1-3: Windows Forms-based HTML downloader
Visual Basic .NET: HtmlDownloadForm
... ' This method is called when the user clicks on the download button Private Sub btnDownload_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDownload.Click
' Set the wait cursor so the user knows that the application ' is going to do something Cursor = Cursors.WaitCursor
' The WebClient class can be used to quickly upload/download data Dim client As New WebClient()
' The call to DownloadData is placed in a Try block because there is ' a reasonable chance that it will throw an exception. Try ' Call DownloadData passing in the URL that was entered into the UI ' Return the byte array back into the content variable. Dim content = client.DownloadData(Me.txtUrl.Text)
' Use the ASCII encoder to convert the byte array to a string ' that can be displayed. Me.txtDisplay.Text = Encoding.ASCII.GetString(content)
Catch ex As Exception ' Display the exception if there is one MsgBox(ex.ToString) End Try
' Reset the cursor to normal because the operation is finished. Cursor = Cursors.Default End Sub End Class |
C# .NET: HtmlDownloadForm
... // This method is called when the user clicks on the download button private void btnDownload_Click(object sender, System.EventArgs e) { // Set the wait cursor so the user knows that the application // is going to do something Cursor = Cursors.WaitCursor;
// The WebClient class can be used to quickly upload/download data WebClient client = new WebClient();
// The call to DownloadData is placed in a Try block because there is // a reasonable chance that it will throw an exception. try { // Call DownloadData passing in the URL that was entered into the UI // Return the byte array back into the content variable. byte[ ] content = client.DownloadData(this.txtUrl.Text);
// Use the ASCII encoder to convert the byte array to a string // that can be displayed. this.txtDisplay.Text = Encoding.ASCII.GetString(content); } catch(Exception ex) { // Display the exception if there is one MessageBox.Show(ex.ToString()); } // Reset the cursor to normal because the operation is finished. Cursor = Cursors.Default; } } |
Windows Services: Windows Services are available through the System.ServiceProcess namespace. The System.ServiceProcess classes enable you to create long-running executable applications that run in their own session commonly known as a service. Windows Services are extremely useful for performing routine operations. For example, using Windows Services and the networking classes, you can write an application that checks to see if portions of your Web site are responsive. You can also use services in conjunction with other application models to move data around on scheduled intervals. For example, an ASP.NET page might be rendered using local data that’s updated every five minutes through execution of a Windows Service. The following sample demonstrates a Windows Service that downloads a particular file every five minutes.
Visual Basic .NET: Windows Service File Downloader
... ' This method is called once the service time has gone off Private Sub tmrDownloadTimer_Elapsed(ByVal sender As System.Object, ByVal e As System.Timers.ElapsedEventArgs) Handles tmrDownloadTimer.Elapsed
' Wrap in a try/catch block as this call could fail Try
' WebClient provides methods for performing basic ' network operations such as resolving a URI. Dim client As New WebClient()
' Downloads the specified URL and saves it to a file ' Note that you may want to specify a path for the file ' rather than saving it to the default directory client.DownloadFile("http://www.contoso.com", "downloadfile.htm")
Catch ex As Exception
' In case it fails, write an exception to the download file Dim writer As New StreamWriter("downloadfile.htm") writer.Write("The following error occurred. " + ex.ToString()) writer.Close() End Try
' Disable download timer Me.tmrDownloadTimer.Enabled = False End Sub … |
C# .NET: Windows Service File Downloader
... ... // This method is called once the service time has gone off private void tmrDownloadTimer_Tick(object sender, System.Timers.ElapsedEventArgs e) { // Wrap in a try/catch block as this call could fail try { // WebClient provides methods for performing basic // network operations such as resolving a URI. WebClient client = new WebClient();
// Downloads the specified URL and saves it to a file // Note that you may want to specify a path for the file // rather than saving it client.DownloadFile("http://www.contoso.com", "downloadfile.htm"); } catch(Exception ex) { // In case it fails, write an exception to the download file StreamWriter writer = new StreamWriter("downloadfile.htm"); writer.Write("The following error occurred. " + ex.ToString()); writer.Close(); } // Disable download timer this.tmrDownloadTimer.Enabled = false; } … |
Console: The console is accessible through the System.Console class, which is the most basic application model in the .NET Framework. Although the model is quite simple, the console is still an extremely powerful application environment. Many developers prefer the console to other application models because of its inherent simplicity.
The console is a great place for network applications. The most common types of network applications in the console are utility applications that perform some discrete set of functions related to the network. For example, you might want to use a console-based application that sends PING requests to a supplied IP address to determine if a particular node is available on the network. Or you might want a console application that downloads a set of files to make a local backup on demand. Web crawlers that download pages on the Internet or an intranet and follow the links are also often written as console applications. Console applications offer a great laboratory in which to develop network logic that can later be moved into a more complex application environment.
The following sample demonstrates a console application that prompts the user for input that’s used to resolve a URL and store its contents to a file, as shown in Figure 1-4.
Figure 1-4: Console-based file downloader
Visual Basic .NET: Console-Based File Downloader
Imports System.Net
' This application prompts the console for ' a URL to be downloaded and a file name. It then ' resolves the URL and stores its contents in the ' specified file. Module FileDownloader
Sub Main()
Dim address As String Dim fileName As String Dim client As New WebClient()
' Prompt for the URL to download Console.Write("Enter the HTTP address of the file to download:") address = Console.ReadLine
' Prompt for the name of the file to be saved Console.Write("Enter the file name to save this file as:") fileName = Console.ReadLine
Try ' DownloadFile will download the URL supplied in address ' and save it to the file specified in fileName client.DownloadFile(address, fileName) Catch e As Exception Console.WriteLine(e.ToString()) End Try End Sub End Module |
C# .NET: Console-Based File Downloader
using System; using System.Net;
/// <summary> /// This application prompts the console for /// a URL to be downloaded and a file name. It then /// resolves the URL and stores its contents in the /// specified file. /// </summary> class FileDownloader { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main(string[ ] args) { string address; string fileName; WebClient client = new WebClient();
// Prompt for the URL to download Console.Write("Enter the HTTP address of the file to download:"); address = Console.ReadLine();
// Prompt for the name of the file to be saved Console.Write("Enter the file name to save this file as:"); fileName = Console.ReadLine();
try { // DownloadFile will download the URL supplied in address // and save it to the file specified in fileName client.DownloadFile(address, fileName); } catch(Exception ex) { Console.WriteLine(ex.ToString()); } } } |
Of the namespaces listed in Table 1-1, three base class namespaces focus explicitly on enabling you to develop rich networking scenarios:
System.Net.*,
System.Runtime.Remoting, and
System.Web.*.
A number of other classes and patterns in the .NET Framework are often useful when it comes to developing applications that interact with the network. This section provides a brief overview of the elements that will be covered in this book and describes why they are often used by network developers.
Applications interacting with the network, or with any other resource for that matter, usually need to accomplish one or more of the following:
Read input data for the purpose of further processing
Write output data for the purpose of further processing by some external entity or by the same application at a later time
The pattern in the .NET Framework for reading and writing data is known as the Stream pattern. As you’ll see in another chapter, the Stream pattern is an incredibly powerful element in the framework because once you learn it, you’ll know how to make your application interact with nearly any type of resource available to the system on which it’s running.
One commonality among network applications is that they tend to perform tasks that can often be time consuming. Sure, the data can be moving around the world at speeds that are baffling, but even 500 milliseconds can turn into a long delay if not properly handled by the application. Applications must go to great lengths to always act responsively to user input. Have you ever used an application that seemed to freeze or hang as it requested information over the network? If so, you know that this can be a very frustrating experience. The .NET Framework supports two key concepts that, when used properly, help to eliminate the frustration caused by an unresponsive application that’s waiting on the network. These concepts are threading and the asynchronous API pattern. The threading support in the framework makes it easy to perform expensive network operations on a thread other than the main thread of execution, which leaves the main thread free to respond to user input in the case of client applications. For server applications, threading can be fine-tuned to maximize hardware utilization and improve the experience of the client interacting with the server. |
|
The .NET Framework also includes a model for calling methods asynchronously. This option gives you many of the same benefits as threading in that you can make a method call on the main thread of execution and quickly return even if the call is one that would block for a long time if called synchronously. The trick comes in the fact that when you make that asynchronous call, a callback method is supplied. The framework then processes the call on another thread and calls your callback once the work is done. The big difference between the asynchronous pattern and using the threading support directly is that the framework and the underlying CLR thread pool will take care of threading semantics for you in the asynchronous case. All the classes that support asynchronous execution calls follow this common pattern, so if you learn the pattern for one class, you will have learned it for the whole framework.
Serialization is the process by which objects are converted from instance (object) format to a serial or stream format that can be sent across the network. Deserialization is the process of converting that same serialized object back into an instance. Serialization can occur through different formats. For example, binary and SOAP are two formats supported by the .NET Framework. Serialization can also involve different transports. For example, using the .NET Framework, a serialized object can be sent from one machine to another over TCP or over HTTP. Both the format and the transport used can have a significant impact on the ability of one node to interoperate with another. Serialization is a key part of building network applications because it forms the basis by which objects are moved from one application instance to another.
Many applications that use the network do so because they want to access resources. To facilitate the naming of resources, the International Engineering Task Force (IETF) created a standard called the URI (rfc2396). URIs are a critical part of network application development because they enable developers to create names for resources that are globally unique. They also enable applications to decouple a resource on the network from the protocol that is used to retrieve that resource. URIs in the .NET Framework are represented by the System.Uri class.
System.Net contains the core networking classes that make up the base transport layer for the .NET Framework. The System.Net namespace includes classes for working with sockets, TCP, UDP, and higher level protocols such as HTTP and File Transfer Protocol (FTP).
The System.Web.Services namespace contains classes for creating and consuming Web services. Web services are a set of APIs that enable developers to expose a set of functionality to Web users over the SOAP protocol. Using Web services, you can build applications that interact and interoperate with other nodes on the network and scale to Internet proportions.
System.Runtime.Remoting contains a framework for creating and executing objects in a distributed manner. It has an extensible architecture that lets you plug in just about any element of the stack, from the transport used to manipulate the object to the payload serialization format with which it is represented.
Security is critical in a networked world. When designing a networked application, developers must constantly be aware of security because most network programs are made interesting by the data or users that are interacting with them. If either of those elements is compromised, the application becomes less useful at best and highly dangerous at worst. The .NET Framework and the underlying CLR were designed from the ground up with network security in mind.
Network applications often include requirements for high performance. Interactive client applications must remain snappy as the user interacts with resources over the network. Server-side content applications need to perform well to serve the maximum number of clients possible in a timely fashion. Network performance can be a complex and challenging space. The .NET Framework does quite a bit to simplify the process of writing high-performance network applications; however, a few key factors should be considered when writing a network application with the .NET Framework to ensure that you get the most out of your client, server, peer, and the network that they use to interact.
Because the .NET Framework is in active development, Microsoft is working on a number of new components related to distributed programming. In Chapter 15, we’ll take a brief look at a number of the exciting trends in network development that are driving this work and discuss ways in which your applications can take advantage of these trends to provide a better user experience. We'll also point out some related areas where we expect to see more support in the framework to help your applications get the most out of the network.