Chapter 4

Accessing the Internet

IN THIS CHAPTER

Bullet Taking a tour of the System.Net namespace

Bullet Using built-in tools to access the network

Bullet Making the network tools work for you

The .NET Framework is designed from the ground up to take the Internet and networking in general into consideration. Not surprisingly, the emphasis on connectivity in every form is nowhere more clear than it is in the System.Net namespace (https://docs.microsoft.com/dotnet/api/system.net). The Internet takes first chair here, with web tools taking up 13 of the classes in the namespace.

System.Net is a big, meaty namespace, and finding your way around it can be difficult, so this chapter begins with an overview of the namespace. The chapter then discusses tasks that you perform often and shows the basics of performing them. Next, you find out about the tools to research complex features of the classes.

Networking is a big part of the .NET Framework, and all the functionality is in this namespace. An entire book can be (and has been) written on the subject. For the purposes of this introduction to networking with C#, this chapter shows you the following features:

  • Getting a file from the network
  • Sending email
  • Logging transfers
  • Checking the status of the network around your running application

Keep in mind that sockets, IPv6, and other advanced Internet protocols are important, but many developers don't currently use them every day. This chapter talks about the parts of the namespace that you will use every day. As always, there is more to discover about System.Net.

Remember You don’t have to type the source code for this chapter manually. In fact, using the downloadable source is a lot easier. You can find the source for this chapter in the CSAIO4D2EBK03CH04 folder of the downloadable source. See the Introduction for details on how to find these source files.

Getting to Know System.Net

The System.Net namespace is full of classes that are confusing if viewed in the documentation, but make a lot of sense when used in an application. The namespace removes all the complexity of dealing with the various protocols used on the Internet.

There are more than 4,000 RFCs for Internet protocols (an RFC is a Request For Comments, a document that is sent to a standards body for review by peers before it becomes a standard). You can obtain copies of these RFCs in locations such as https://www.rfc-editor.org/standards and http://www.faqs.org/rfcs/. If you have to learn all the RFCs separately, you'll never complete your project. The System.Net namespace is about making network coding less painful.

System.Net isn't just for web projects. Like everything else in the base class library, you can use System.Net with all kinds of projects. You can

  • Get information from web pages on the Internet and use it on your programs.
  • Move files via the Internet using FTPs.
  • Send email easily.
  • Use more advanced network structures.
  • Secure communications over the Internet using the SSL protocol.

If you need to check on the connectivity of a computer from a Windows application, you can use System.Net. If you need to build a class that will download a file from a website, System.Net is the namespace you need. Just because most classes relate to the Internet doesn't mean that only web applications can use it. That’s the magic of System.Net. Any application can be connected to another application through an Application Programming Interface (API) that you access using System.Net functionality. While some parts of the namespace function to make the development of web applications easier, the namespace in general is designed to make any application work with networks that adhere to web standards (including an intranet accessible within your organization).

How Net Classes Fit into the Framework

The System.Net namespace contains a large number of classes and smaller namespaces. The number of classes and namespaces increases with each version of the .NET Framework, so it pays to look after each update to see what new goodies are present. The number may seem overwhelming. However, if you look closely, you can see patterns. The following sections discuss the smaller namespaces and provide a listing of essential System.Net namespace classes.

Understanding the System.Net subordinate namespaces

When you view the System.Net documentation at https://docs.microsoft.com/dotnet/api/system.net, you see a few subordinate namespaces listed in the “See Also” section of the page. However, this isn't a complete list, and there really are a number of additional subordinate namespaces you need to know about, as shown in Table 4-1. The Latest Full Implementation column tells you the latest version of .NET that contains the full set of classes for the namespace. Later versions may remove some functionality from the namespace.

TABLE 4-1 A Listing of Important System.Net-Associated Namespaces

Namespace

Purpose

Latest Full Implementation

Link

System.Net.Cache

A cache provides the means to improve application performance by storing commonly used resources. This namespace works with the WebRequest and HttpWebRequest classes to improve web-based application speed by creating cache policies.

6.0

https://docs.microsoft.com/dotnet/api/system.net.cache

System.Net.Configuration

Manages the configuration settings for web-based applications. These settings affect all the other System.Net namespaces and classes.

4.8

https://docs.microsoft.com/dotnet/api/system.net.configuration

System.Net.Http

Provides the functionality needed to create HTTP applications. It's where you find the client, content, message, request, and response-oriented classes. The .NET Framework 5.0 provides some enhancements to this namespace.

6.0

https://docs.microsoft.com/dotnet/api/system.net.http

System.Net.Http.Headers

Contains the classes for managing the headers used with the System.Net.Http namespace. In many cases, these headers are defined as part of RFC 2616 (http://www.faqs.org/rfcs/rfc2616.html).

6.0

https://docs.microsoft.com/dotnet/api/system.net.http.headers

System.Net.Mail

Allows sending (not receiving) of email using the Simple Mail Transfer Protocol (SMTP). The classes follow RFC 2821 (http://www.faqs.org/rfcs/rfc2821.html) among other standards.

6.0

https://docs.microsoft.com/dotnet/api/system.net.mail

System.Net.Mime

Contains classes that provide Multipurpose Internet Mail Exchange (MIME) support for the Content-Type, Content-Disposition, and Content-transfer-Encoding headers used with the SmtpClient class. The classes follow RFC 2045 (http://www.faqs.org/rfcs/rfc2045.html) among other standards.

6.0

https://docs.microsoft.com/dotnet/api/system.net.mime

System.Net.NetworkInformation

Obtains network data that includes traffic data, network address information, and notification of address changes for the local computer. This is also where you find an implementation of the Ping utility (https://docs.microsoft.com/dotnet/api/system.net.networkinformation.ping) that allows verification of remote host status.

6.0

https://docs.microsoft.com/dotnet/api/system.net.networkinformation

System.Net.PeerToPeer

Provides access to peer-to-peer networking functionality. It provides an implementation of the Peer Name Resolution Protocol (PNRP) discussed at https://docs.microsoft.com/dotnet/framework/network-programming/peer-name-resolution-protocol.

4.8

https://docs.microsoft.com/dotnet/api/system.net.peertopeer

System.Net.PeerToPeer.Collaboration

Enhances the System.Net.PeerToPeer namespace functionality. It provides the functionality needed for serverless managed collaboration sessions.

4.8

https://docs.microsoft.com/dotnet/api/System.Net.PeerToPeer.Collaboration

System.Net.Security

Allows secure communication using network streams. This namespace received significant updates in .NET 5.0 and .NET 6.0.

6.0

https://docs.microsoft.com/dotnet/api/System.Net.Security

System.Net.Sockets

Implements Windows Sockets (Winsock) functionality (see https://docs.microsoft.com/windows/win32/winsock/getting-started-with-winsock for details), which allows firm control over network communications.

4.8

https://docs.microsoft.com/dotnet/api/System.Net.Sockets

System.Net.WebSockets

Implements Web Sockets (WebSocket) functionality (see https://docs.microsoft.com/aspnet/core/fundamentals/websockets for details), which allows two-way persistent communication channels over TCP connections. The .NET Framework 6.0 provides some enhancements to this namespace.

6.0

https://docs.microsoft.com/dotnet/api/System.Net.WebSockets

Working with the System.Net classes

The System.Net classes are well named, and you will note that a few protocols get a number of classes each. After you translate the entry names, you can narrow down what you need based on the way the protocol is named:

  • Authentication and Authorization: These classes provide security.
  • Cookie: This class manages cookies from web browsers and usually is used in ASP.NET pages.
  • DNS (Domain Name Services): These classes help to resolve domain names into IP addresses.
  • Download: This class is used to get files from servers.
  • EndPoint: This class helps to define a network node.
  • FileWeb: This brilliant set of classes describes network file servers as local classes.
  • FtpWeb: This class is a simple File Transfer Protocol implementation.
  • Http (HyperText Transfer Protocol): This class is the web protocol.
  • IP (Internet Protocol): This class helps to define network endpoints that are specifically Internet related.
  • NetworkCredential: This class is another security implementation.
  • Service: This class helps manage network connections.
  • Socket: This class deals with the most primitive of network connections.
  • Upload: This set of classes helps you upload information to the Internet.
  • Web: These classes help with the World Wide Web — largely implementations of the http classes that are more task oriented.

This list is extensive because the classes build on each other. The EndPoint classes are used by the socket classes to define certain network specifics, and the IP classes make them specific to the Internet. The Web classes are specific to the World Wide Web. You will rarely use the highest-level classes, but it's often tough to see what is needed when. Most of the functions that you use every day, though, are encapsulated within the namespaces found in Table 4-1.

Using the System.Net Namespace

The System.Net namespace is code oriented, which means that few implementations are specifically for user interfaces. Almost everything that you do with these classes is behind the scenes. You have few drag-and-drop user controls — the System.Net namespace is used in the Code View. To demonstrate this fact, the examples in the remainder of the chapter build a Windows Forms application that has the following requirements:

  • Check the network status.
  • Get a specific file from the Internet.
  • Email it to a specific email address (or addresses).
  • Log the whole transaction.

Checking the network status

First, you need to inform the user about network connectivity using the NetworkTools example. To begin, create a Windows Forms application using the same steps as found in the “Creating the data access project” section of Chapter 2 of this minibook (making the requisite changes for example name and location), and then follow these steps when you see the form displayed:

  1. Add a StatusStrip control to the lower left of the form by dragging it from the Menus & Toolbars group of the Toolbox.

    The StatusStrip automatically takes up the entire bottom area of the form.

  2. Select the SmartTag that appears on the left side of the StatusStrip and add three StatusLabels.

    Figure 4-1 shows how the dropdown entries appear when you click the down arrow in the box.

    Snapshot of many controls come with SmartTags that let you configure them easily.

    FIGURE 4-1: Many controls come with SmartTags that let you configure them easily.

  3. Select each StatusLabel in turn and configure it for displaying network and application status.

    Configure your StatusLabel controls like this:

    • toolStripStatusLabel1: Set (Name) to NetStatus and Text to Not Connected.
    • toolStripStatusLabel2: Set (Name) to PictureStatus and Text to Not Downloaded.
    • toolStripStatusLabel3: Set (Name) to EmailStatus and Text to No Email Sent.0

    Figure 4-2 shows how your StatusStrip should appear at this point.

    Snapshot of configuring the StatusStrip to provide the user with useful information.

    FIGURE 4-2: Configure the StatusStrip to provide the user with useful information.

  4. Double-click the form.

    Visual Studio creates the Form1_Load() method and displays the Code Editor for you.

  5. Reference the System.Net namespace by adding the line using System.Net.NetworkInformation; to the top of the code.
  6. Add the following code to Form1_Load() to test whether the network is available and display it on the status bar:

    private void Form1_Load(object sender, EventArgs e)
    {
    if (NetworkInterface.GetIsNetworkAvailable())
    {
    NetStatus.Text = "Connected";
    }
    else
    {
    NetStatus.Text = "Disconnected";
    }
    }

That's all there is to it. The NetworkInformation class contains a bunch of information about the status of the network, current IP addresses, the gateway being used by the current machine, and more.

Tip Keep in mind that the NetworkInformation class will work only on a local machine. If you use this class in an ASP.NET Web Forms application, you will get information about the server.

Downloading a file from the Internet

You can get a file from the Internet in one of several ways, and one of the most common is by using hypertext transfer protocol (HTTP). You can find something to download from HTTP sites across the web today, so it's an important protocol to know. To build an application that uses HTTP, start with the example from the previous section and follow these steps:

  1. Drag a Button control onto the form from the Toolbox.
  2. Type &Download in the button’s Text property and btnDownload in the button's (Name) property.
  3. Double-click the button.

    Visual Studio creates the btnDownload_Click() method and displays the Code Editor for you.

  4. Add the following imports to the top of the coding area:

    using System.Net;
    using System.IO;

  5. Create a new method called DownloadFile that accepts a remoteFile and a localFile as type string.
  6. Type the following code into the DownloadFile() method:

    private void DownLoadFile(string remoteFile, string localFile)
    {
    // Create the stream and request objects.
    FileStream localFileStream = File.Create(localFile);
    HttpWebRequest httpRequest =
    (HttpWebRequest)WebRequest.Create(remoteFile);

    // Configure the request.
    httpRequest.Method = WebRequestMethods.Http.Get;

    // Configure the response to the request.
    WebResponse httpResponse = httpRequest.GetResponse();
    Stream httpResponseStream = httpResponse.GetResponseStream();
    byte[] buffer = new byte[1024];

    // Process the response by downloading data.
    int bytesRead = httpResponseStream.Read(buffer, 0, 1024);
    while (bytesRead > 0)
    {
    localFileStream.Write(buffer, 0, bytesRead);
    bytesRead = httpResponseStream.Read(buffer, 0, 1024);
    }

    // Close the streams.
    localFileStream.Close();
    httpResponseStream.Close();

    // Update the status strip.
    PictureStatus.Text = "Picture Downloaded";
    }

    The code follows a process of establishing a connection, configuring the connection, configuring a response to that connection, and then performing a task. In this case, the task is to download a file from the HTTP site. You must always close the streams when you finish performing a task.

  7. Call the DownloadFile() method from the btnDownload_Click() event handler by using the following code:

    private void btnDownload_Click(object sender, EventArgs e)
    {
    // Obtain the file.
    DownLoadFile(@"http://blog.johnmuellerbooks.com/" +
    "wp-content/uploads/2014/06/cropped-country01-1.jpg",
    @"c: empCountry_Scene.jpg");
    }

Remember To use this example, you must replace the first string with the location of a file on your HTTP site and the second string with the location on your hard drive where you want the file to go. In this HTTP example, the WebRequest and WebResponse classes in the System.Net namespace are fully utilized to create the more complete HttpWebRequest and properties such as the method of download.

In fact, the toughest part of this process is dealing with a FileStream object, which is still the best way to move files and is not specific to the System.Net namespace. Streams are discussed in Chapter 3 of this minibook, which covers the System.IO namespace, but they have significance to the network classes too. Streams represent a flow of data of some kind, and a flow of information from the Internet qualifies.

That's what you are doing when you get a web page or a file from the Internet — gathering a flow of data. If you think about it, it makes sense that this is a flow, because the status bar in an application shows a percentage of completion. Just like pouring water into a glass, the flow of data is a stream, so the concept is named Stream.

Emailing a status report

Email is a common requirement of networked systems. This example works fine with your personal email, but you need to know the SMTP server address (required when you set up your email application), your username, and your password to make it work. If you are working in an enterprise environment, you are going to write a larger-scale application to handle all email requirements, rather than make each individual application email-aware. However, if you are writing a stand-alone product, it might require email support.

  1. Add four TextBox controls named EmailAddress, SMTPServer, Username, and Password, and four Label controls to the default form in Design View.

    Your form should look similar to the one shown in Figure 4-3.

    Snapshot of configuring the form to accept email information.

    FIGURE 4-3: Configuring the form to accept email information.

  2. Change to Code View.
  3. Add the following imports to the top of the coding area:

    using System.Net.Mail;

  4. Create a new method called SendEmail() that accepts fromAddress, toAddress, subject, and body, all of type string.

    It should accept the from email address, the to email address, the subject of the email, and the body of the email.

  5. Type the following code into the SendEmail() method:

    private void SendEmail(string fromAddress, string toAddress,
    string subject, string body)
    {
    // Define the message.
    MailMessage message =
    new MailMessage(fromAddress, toAddress, subject, body);

    // Configure the credentials.
    NetworkCredential Creds =
    new NetworkCredential(Username.Text, Password.Text);

    // Create the connection and send the message.
    SmtpClient mailClient = new SmtpClient(SMTPServer.Text)
    {
    Credentials = Creds
    };
    mailClient.Send(message);

    // Release the message and client.
    message = null;
    mailClient = null;

    // Update the status strip.
    EmailStatus.Text = "Email Sent";
    }

The example follows a process that starts by creating a message. It then creates a client that provides the connection to the host and sends the message to the host. Notice that you must provide credentials (in most cases) to access the STMP server, and that you add these as part of the SmtpClient configuration as Credentials. The last step is to release the message and client so that the garbage collector can reclaim them.

After you have written your method, you need to call it after the file is downloaded in the btnDownload_Click() event handler. Change the code of that subroutine to the following to call that method:

private void btnDownload_Click(object sender, EventArgs e)
{
// Obtain the file.
DownLoadFile(@"http://blog.johnmuellerbooks.com/" +
"wp-content/uploads/2014/06/cropped-country01-1.jpg",
@"c: empCountry_Scene.jpg");

// Send a success message.
SendEmail(EmailAddress.Text, EmailAddress.Text,
"HTTP Successful", "Picture Successfully Downloaded");
}

The example uses the value of the EmailAddress text box twice: once for the to address, and once for the from address. This isn't always necessary, because you may have a situation in which you want the email to come only from a webmaster address or to go only to your address.

To run the application, provide your email address, SMTP server address, username, and password in the fields of the form. When you click Download, the application should download the file to the local drive and then email you to inform you that the download is complete. You will also see status information at the bottom of the application. A host of things can go wrong with network applications, though, and you should be aware of them. Here are a few:

  • For most network activity, the machine running the software must be connected to a network. This isn’t a problem for you as the developer, but you need to be conscious of the end users, who may need connectivity to have access to the features they want to use. Use of the network status code can help inform users about the availability of those features.
  • Firewalls and other network appliances sometimes block network traffic from legitimate applications. Some examples of this include:
    • Network analysis features of .NET are often blocked on corporate servers. If the server is available to the public, these openings can cause holes for hackers to crawl through.
    • Speaking of hackers, make sure that if you use incoming network features in your application, you have adequately secured your application. More on this can be found in the excellent book Writing Secure Code, Second Edition, by Michael Howard and David C. LeBlanc (published by Microsoft Press).
    • Email is especially fragile. Often, Internet service providers will block email from an address that is not registered on a mail server. This means that if you are using your localhost server, your ISP might block the email.
  • Network traffic is notoriously hard to debug. For instance, if the sample application works, but you never receive an email from the SmtpServer you coded, what went wrong? You may never know.

Logging network activity

This brings you to the next topic, which is network logging. Because network activity problems are so hard to debug and reproduce, Microsoft has built in several tools for the management of tracing network activity.

What’s more, as with the ASP.NET tracing available, the System.Net namespace tracing is completely managed using the configuration files. To be able to use the functions, therefore, you don't need to change and recompile your code. In fact, with a little management, you can even show debug information to the user by managing the config files your application uses.

Each kind of application has a different kind of configuration file. For Windows Forms applications, which you are using here, the file is called app.config and is stored in the development project directory. When you compile, the name of the file is changed to the name of the application, and it's copied into the bin directory for running.

If you open your app.config file now by double-clicking its entry in Solution Explorer, you see that it has practically nothing in it (as shown in Listing 4-1). This is fairly new for .NET, which used to have very involved configuration. You will add some content to the configuration to get tracing turned on. Note that your .NETFramework,Version version number may vary from the one shown.

LISTING 4-1 The Default app.config File

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0"
sku=".NETFramework,Version=v4.7.2"/>
</startup>
</configuration>

First, you need to add a new source for the System.Net namespace. Next, you add a switch to the switches section for the source you added. Finally, you add a sharedlistener to that section and set the file to flush the tracing information automatically. The finished app.config file, with the additions in bold, is shown in Listing 4-2.

LISTING 4-2 The Finished app.config File

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0"
sku=".NETFramework,Version=v4.5.2"/>
</startup>
<system.diagnostics>
<sources>
<source name="System.Net">
<listeners>
<add name="System.Net"/>
</listeners>
</source>
</sources>
<switches>
<add name="System.Net" value="Verbose" />
</switches>
<sharedListeners>
<add name="System.Net"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="my.log"/>
</sharedListeners>
<trace autoflush="true" />
</system.diagnostics>
</configuration>

Run the application again and watch the Output window. Advanced logging information is shown there because of your changes to the configuration file. Additionally, a log file was written. In the development environment, this is in the bin/debug directory of your project. You might have to click the Show All Files button at the top of the Solution Explorer to see it.

In that folder, you should see the file named my.log, where the SharedListener you added to the app.config file directed the logging information. Listing 4-3 shows how the content of this file could appear. The specific URLs, reference numbers, and other object values will differ in your output, but you should see something similar to the output shown here (which has been edited for brevity):

System.Net Verbose: 0 : [15048] Entering WebRequest::Create(http://blog.johnmuellerbooks.com/wp-content/uploads/2014/06/cropped-country01-1.jpg)
System.Net Verbose: 0 : [15048] Entering HttpWebRequest#33675143::HttpWebRequest(http://blog.johnmuellerbooks.com/wp-content/uploads/2014/06/cropped-country01-1.jpg#-113598309)
System.Net Information: 0 : [15048] Current OS installation type is 'Client'.
System.Net Information: 0 : [15048] RAS supported: True
System.Net Verbose: 0 : [15048] Exiting HttpWebRequest#33675143::HttpWebRequest()
System.Net Verbose: 0 : [15048] Exiting WebRequest::Create() -> HttpWebRequest#33675143
System.Net Verbose: 0 : [15048] Entering HttpWebRequest#33675143::GetResponse()

System.Net Information: 0 : [15048] HeaderCollection#39451090::Get(MIME-Version)
System.Net Information: 0 : [15048] HeaderCollection#39451090::Get(From)
System.Net Information: 0 : [15048] HeaderCollection#39451090::Get(To)
System.Net Information: 0 : [15048] HeaderCollection#39451090::Get(Date)
System.Net Information: 0 : [15048] HeaderCollection#39451090::Get(Subject)
System.Net Information: 0 : [15048] HeaderCollection#26753075::Get(Content-Type)
System.Net Information: 0 : [15048] HeaderCollection#26753075::Get(Content-Transfer-Encoding)
System.Net Information: 0 : [15048] HeaderCollection#26753075::Get(Content-Transfer-Encoding)
System.Net Information: 0 : [15048] HeaderCollection#26753075::Get(Content-Transfer-Encoding)
System.Net Verbose: 0 : [15048] Exiting SmtpClient#13869071::Send()

Reading this file, you can see that the reference numbers that match the requests on the server all appear, dramatically improving the ease of debugging. Also, because everything is in order of action, finding out exactly where the error occurred in the process is much easier.

One of the more interesting entries is the series of three commands used to retrieve each block of data for the picture. The ConnectStream exits the previous read, enters a new read, and then downloads the data like this (along with the actual binary data):

System.Net Verbose: 0 : [15048] Exiting ConnectStream#47891719::Read() -> Int32#1024
System.Net Verbose: 0 : [15048] Entering ConnectStream#47891719::Read()
System.Net Verbose: 0 : [15048] Data from ConnectStream#47891719::Read

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset