< C++/CLI Web Class Performance Measurement Program Example | Main | Chap 15 TOC: Advancement in .NET Framework Networking >

 


 

 

Chapter 14 Part 6:

Network Performance and Scalability

 

 

What do we have in this chapter 14 Part 6?

  1. Build and Run the C++/CLI Project

  2. Managing HTTP Verbs

  3. Authentication

Build and Run

 

Build the project and make sure there is no error.

 

A Simple C++/CLI Web Class Performance Measurement Program Example: building the project

 

Without error during the build stage, run the project without debugging.

 

A Simple C++/CLI Web Class Performance Measurement Program Example: running the project without debugging

 

The following screenshot shows a sample console output. This program needs to be run at the command prompt.

 

A Simple C++/CLI Web Class Performance Measurement Program Example: a sample of the console output

 

Invoke the command prompt through the run command or Start > All Programs > Accessories > Command Prompt short cut menu or through the Visual Studio Tools. Then, run the project from command line.

 

A Simple C++/CLI Web Class Performance Measurement Program Example: invoking the Windows command prompt from the Visual Studio 2008 tools short cut menu

 

The command line argument used in this sample run is:

 

fastgetcp -a -c 5 -n 7 -u http://msdn.microsoft.com/en-us/visualc/aa336402.aspx

 

The following screenshot shows a sample console output.

 

A Simple C++/CLI Web Class Performance Measurement Program Example: a sample of console output when run from the command prompt with the chosen arguments

 

To compare the 'performance', use different –n and –c values for the arguments. A complete sample console output for the previous sample run is given in the following para.

C:\networkdotnetproject\FastGetCP\Debug>fastgetcp

In main()...

In FastAsyncGetCP::TestMain()

In FastAsyncGetCP::usage()

usage: fastgetcp -c [int] -n [int] -u [URI] -p

 -a              Allow unsafe authenticated connections

 -c  int         Number of concurrent requests allowed

 -d              Disable Nagle algorithm

 -n  int         Total number of connections to make

 -u  URI         URI resource to download

 -p              Enable pipelining

 -un string      User name

 -up string      Password

 -ud domain      Domain

 

C:\networkdotnetproject\FastGetCP\Debug>fastgetcp -a -c 5 -n 7 -u http://msdn.microsoft.com/en-us/visualc/aa336402.aspx

In main()...

In FastAsyncGetCP::TestMain()

Counting start in ms: 7181734

Getting the pages...

In FastAsyncGetCS::GetPages()

In FastAsyncGetCS::ResponseCallback()

In FastAsyncGetCS::ReadCallBack()

In FastAsyncGetCS::ReadCallBack()

[trimmed]

In FastAsyncGetCS::ReadCallBack()

In FastAsyncGetCS::ReadCallBack()

In FastAsyncGetCS::ResponseCallback()

In FastAsyncGetCS::ReadCallBack()

In FastAsyncGetCS::ReadCallBack()

[trimmed]

In FastAsyncGetCS::ReadCallBack()

In FastAsyncGetCS::ReadCallBack()

In FastAsyncGetCS::ResponseCallback()

In FastAsyncGetCS::ReadCallBack()

In FastAsyncGetCS::ReadCallBack()

[trimmed]

In FastAsyncGetCS::ReadCallBack()

In FastAsyncGetCS::ReadCallBack()

In FastAsyncGetCS::ResponseCallback()

In FastAsyncGetCS::ReadCallBack()

In FastAsyncGetCS::ReadCallBack()

[trimmed]

In FastAsyncGetCS::ReadCallBack()

In FastAsyncGetCS::ReadCallBack()

In FastAsyncGetCS::ResponseCallback()

In FastAsyncGetCS::ReadCallBack()

In FastAsyncGetCS::ReadCallBack()

[trimmed]

In FastAsyncGetCS::ReadCallBack()

In FastAsyncGetCS::ReadCallBack()

Counting end in ms: 7195031

Total count for the elapsed time in ms: 13297

Calculating the total KB/s...

Then total count in seconds 13.297 seconds.

Number of requests in the elapsed time: 0.5264345 requests per second.

It is 20 KB per second.

 

C:\networkdotnetproject\FastGetCP\Debug>

Managing HTTP Verbs

 

Developers should be aware that the HTTP verb used can impact performance. When performing a POST operation, the server often responds with a 100 Continue after the request has been accepted. This response is typically sent to prevent the client from sending the entire request when the server rejects it. The 100 Continue logic saves network bandwidth and unneeded processing on the client side when a request is rejected; however, it can cause a bottleneck as an extra roundtrip is required to complete the POST request.

An application can explicitly override the 100 Continue behavior by using the ServicePointManager.Expect100Continue property. By default, when a POST is issued, the Framework waits 350 milliseconds before the body is transmitted unless the server responds with a 100 Continue. This timeout is in place in the event that the server simply expects the client to transmit the body. With the default behavior of waiting for a 100 Continue response, a POST operation incurs two roundtrips plus a possible 350-millisecond delay before the request can complete. Setting the Expect100Continue to false would cause the body to be transmitted immediately, bypassing the 350-millisecond delay.

The GET verb can also suffer from a performance roadblock: the Nagle algorithm. A roadblock is especially likely if authentication is involved. When an application posts multiple GET requests to a server, the Nagle algorithm introduces up to a 200-millisecond delay before sending the requests. As we mentioned earlier, Nagling reduces network load by lumping more data into a single packet; this behavior can introduce significant delays, however, since HTTP GET requests tend to be smaller than the Nagle threshold and therefore incur a delay.

 

Authentication

 

Authenticating a request is a powerful and often necessary task. Of course, this process adds extra overhead to the HTTP request that can significantly affect overall performance. The .NET Framework Web classes support several authentication methods, including basic, digest, NTLM, and Kerberos. Each method incurs its own overhead for authenticating a request depending on the efficiency of the underlying protocol. Table 14-4 compares the performance of different authentication types.

 

Table 14-4: HTTP Authentication Performance

 

Authentication Type

Preauthentication

Unsafe Connection Sharing

Requests per Second

CPU Usage

None

No

No

1,322

89

Basic

No

No

1,312

90

Basic

Yes

No

962

91

Digest

No

No

219

63

Digest

Yes

No

511

60

Kerberos

No

No

1,298

59

NTLM

No

No

95

66

NTLM

No

Yes

1,261

100

 

The table shows the number of requests per second when using a given authentication type to retrieve a 1-KB file along with the default connection limit of two. The CPU usage on the client is also listed. Notice how enabling preauthentication increases performance for those authentication types that support it (Basic and Digest). Also notice that enabling the HttpWebRequest.UnsafeAuthenticatedConnectionSharing increases NTLM performance.

As we mentioned in Chapter 10, NTLM authentication occurs on every request as the default behavior. This can lead to server performance penalties, as illustrated by the rate of 95 connections per second shown in Table 14-4. The reason for this performance degradation is in the middle-tier scenario, where a client is making a request to a back-end server while impersonating another user. If UnsafeAuthenticatedConnectionSharing is used carelessly, then the first connection can be established using the Administrators privileges. If the client later impersonates a regular user, subsequent requests are made with Administrator rights. A way to guard against this risk when unsafe connection sharing is enabled is to use the ConnectionGroupName property to associate all requests from one user together, as shown in the following code sample:

 

C#

HttpWebRequest request;

NetworkCredential userJoe, userMike;

 

request = (HttpWebRequest)WebRequest.Create(“http://foo.com”);

userJoe = new NetworkCredential( “Joe", “JoePassWord!” );

userMike = new NetworkCredential( “Mike", “MikePassWord!” );

 

request.Credentials  = userJoe;

request.ConnectionGroupName = userJoe.UserName;

request.UnsafeAuthenticatedConnectionSharing = true;

// Make request for Joe

 

request = (HttpWebRequest) WebRequest.Create(“http://foo.com”);

request.Credentials = userMike;

request.ConnectionGroupName = userMike.UserName;

request.UnsafeAuthenticatedConnectionSharing = true;

// Make request for Mike

 

Visual Basic .NET

Dim request As HttpWebRequest

Dim userJoe As NetworkCredential

Dim userMike As NetworkCredential

 

request = WebRequest.Create("http://foo.com")

userJoe = New NetworkCredential("Joe", "JoePassWord!")

userMike = New NetworkCredential("Mike", "MikePassWord!")

 

request.Credentials = userJoe

request.ConnectionGroupName = userJoe.UserName

request.UnsafeAuthenticatedConnectionSharing = True

‘ Make request for Joe

 

request = WebRequest.Create("http://foo.com")

request.Credentials = userMike

request.ConnectionGroupName = userMike.UserName

request.UnsafeAuthenticatedConnectionSharing = True

‘ Make request for Mike

The sample uses two user credentials for Joe and Mike. Joe’s credentials should not be used when making Mike’s request, so ConnectionGroupName is set to the user’s name for each request. This prevents Mike’s request from executing under Joe’s user credentials. A final note about NTLM authentication is that an extra TCP connection is used each time the client authenticates the supplied user credentials. With the default security (i.e., unsafe authentication disabled), the extra connection can exhaust the local port space causing subsequent HTTP requests to fail with a protocol error. Recall that when a socket is created and bound to port zero, it is actually randomly bound to a local port between 1024 and 5000. Each time a request is made with credentials, an extra TCP connection is created to the server that is bound to a port in this range. Once the credentials are verified, the connection is closed, but it goes into a TIME_WAIT state.

 

 

 


< C++/CLI Web Class Performance Measurement Program Example | Main | Chap 15 TOC: Advancement in .NET Framework Networking >