Access
Implementing asynchronous requests
The System.Net class uses the standard asynchronous programming model of the. Net Framework for asynchronous access to Internet resources. The BeginGetResponse and EndGetResponse methods of the WebRequest class start and complete asynchronous requests for Internet resources, respectively.
AttentionUsing synchronous calls in asynchronous callback methods can result in severe performance degradation. Pass
WebRequestand the Internet request implemented by its descendants must use Stream.beginread to read the stream returned by the WebResponse.GetResponseStream method.
The following C # sample program shows how to pass the
WebRequestClass uses an asynchronous call. The example is a console program that obtains a URI from the command line, requests the resource at this URI, and then prints the data on the console while receiving data from the Internet.
The program defines two classes for its own use: one is
RequestStateclass, which passes data between asynchronous invocations;
Clientgetasyncclass, which implements asynchronous requests for Internet resources.
RequestStateClass preserves the state of the request between the asynchronous method calls that serve the request. In
RequestStateClass that contains the current resource request and the received response stream.
WebRequestAnd Stream instances, buffers that contain data that is currently received from Internet resources, and StringBuilder instances that contain the entire response. When the AsyncCallback method
Webrequest.begingetresponseWhen registering,
RequestStateInstance (AR) as
StateParameter passing.
Clientgetasyncclass implements an asynchronous request to an Internet resource and writes the resulting response to the console. This class contains the methods and properties that are described in the following list.
- The Alldone property contains an instance of the ManualResetEvent class that emits a signal that the request has been completed.
- The Main () method reads the command line and begins a request for the specified Internet resource. This method creates the WebRequest instance wreq and requeststate instance AR, invokes the BeginGetResponse to begin processing the request, and then invokes the Alldone.waitone () method so that the application exits after the callback completes. After reading a response from an Internet resource, Main () writes the response to the console, and the application ends.
- The Showusage () method writes the sample command line to the console. This method is called if Uri,main () is not provided on the command line.
- The Respcallback () method implements an asynchronous callback method for an Internet request. This method creates a WebResponse instance that contains a response from an Internet resource, gets the response stream, and then begins to read the data asynchronously from the stream.
- The Readcallback () method implements an asynchronous callback method that reads the response stream. It transmits data received from Internet resources to the ResponseData property of the RequestState instance, and then initiates another asynchronous read to the response stream until no more data is returned. After all data has been read, Readcallback () closes the response stream and calls the Alldone.set () method to indicate that the response in responsedata is complete.
AttentionShutting down all network streams is critical. If all of the request and response streams are not closed, the application will run out of server connections and not be able to process other requests.
[C #]
Using System;
Using System.Net;
Using System.Threading;
Using System.Text;
Using System.IO;
The RequestState class passes data across async calls.
public class RequestState
{
const int buffersize = 1024;
Public StringBuilder RequestData;
Public byte[] Bufferread;
Public WebRequest Request;
Public Stream Responsestream;
Create Decoder for appropriate enconding type.
Public Decoder Streamdecode = Encoding.UTF8.GetDecoder ();
Public RequestState ()
{
Bufferread = new Byte[buffersize];
RequestData = new StringBuilder (String.Empty);
Request = null;
Responsestream = null;
}
}
Clientgetasync issues the async request.
Class Clientgetasync
{
public static ManualResetEvent alldone = new ManualResetEvent (false);
const int buffer_size = 1024;
public static void Main (string[] args)
{
if (args. Length < 1)
{
Showusage ();
Return
}
Get the URI from the command line.
Uri httpsite = new Uri (Args[0]);
Create the Request object.
WebRequest wreq = WebRequest.Create (httpsite);
Create the state object.
RequestState rs = new requeststate ();
Put the "request" into the "state object" it can be passed around.
Rs. Request = wreq;
Issue the async request.
IAsyncResult r = (IAsyncResult) wreq. BeginGetResponse (
New AsyncCallback (Respcallback), RS);
Wait until the ManualResetEvent are set so this application
does not exit until after the callback is called.
Alldone.waitone ();
Console.WriteLine (Rs. Requestdata.tostring ());
}
public static void Showusage () {
Console.WriteLine ("Attempts to get a URL");
Console.WriteLine ("\r\nusage:");
Console.WriteLine ("Clientgetasync URL");
Console.WriteLine ("Example:");
Console.WriteLine ("Clientgetasync http://www.contoso.com/");
}
private static void Respcallback (IAsyncResult ar)
{
Get the RequestState object from the async result.
RequestState rs = (requeststate) ar. asyncstate;
Get the WebRequest from RequestState.
WebRequest req = Rs. Request;
Call EndGetResponse, which produces the WebResponse object
That's came from the request issued above.
WebResponse resp = req. EndGetResponse (AR);
The Start reading data from the response stream.
Stream Responsestream = resp. GetResponseStream ();
Store the response stream in RequestState to read
The stream asynchronously.
Rs. Responsestream = Responsestream;
Pass Rs. Bufferread to BeginRead. Read data into Rs. Bufferread
IAsyncResult Iarread = Responsestream.beginread (rs. Bufferread, 0,
Buffer_size, New AsyncCallback (Readcallback), RS);
}
private static void Readcallback (IAsyncResult asyncresult)
{
Get the RequestState object from AsyncResult.
RequestState rs = (requeststate) asyncresult.asyncstate;
Retrieve the responsestream that is set in Respcallback.
Stream Responsestream = Rs. Responsestream;
Read Rs. Bufferread to verify that it contains data.
int read = Responsestream.endread (asyncresult);
if (Read > 0)
{
Prepare a Char array buffer for converting to Unicode.
char[] Charbuffer = new Char[buffer_size];
Convert byte stream to Char array and then to String.
Len contains the number of characters converted to Unicode.
int len =
Rs. Streamdecode.getchars (Rs. Bufferread, 0, Buffer_size, charbuffer, 0);
String str = new string (charbuffer, 0, Len);
Append the recently read data to the RequestData StringBuilder
Object contained in RequestState.
Rs. Requestdata.append (
Encoding.ASCII.GetString (Rs. Bufferread, 0, read));
Continue reading data until
Responsestream.endread returns–1.
IAsyncResult ar = Responsestream.beginread (
Rs. Bufferread, 0, Buffer_size,
New AsyncCallback (Readcallback), RS);
}
Else
{
if (Rs. REQUESTDATA.LENGTH>0)
{
Display data to the console.
String strcontent;
Strcontent = Rs. Requestdata.tostring ();
}
Close down the response stream.
Responsestream.close ();
Set the ManualResetEvent so the main thread can exit.
Alldone.set ();
}
Return
}
}
using the Application protocol
The. NET framework supports common application protocols on the Internet. This section contains information about using in the. NET Framework
HTTP、
TCPAnd
UDPSupported information, and about using the
Windows sockets InterfaceThe information that implements the custom protocol.
HTTP
The. NET framework uses the HttpWebRequest and HttpWebResponse classes to provide full support for the HTTP protocol, which makes up most of the Internet traffic. These derived classes from WebRequest and WebResponse are returned by default whenever a static method WebRequest.Create encounters a URI that begins with "http" or "https". In most cases,
WebRequestAnd
WebResponseclass provides everything that is required to build a request, but if you need access to the HTTP-specific functionality exposed as a property, you can convert the types of those classes to
HttpWebRequestOr
HttpWebResponse。
HttpWebRequestAnd
HttpWebResponseEncapsulates a standard HTTP request and response transaction and provides access to common HTTP headers. These classes also support most of the HTTP 1.1 features, including pipelines, block areas, authentication, pre-authentication, encryption, proxy support, server certificate validation, and connection management. Custom headers and headers that are not provided by attributes can be stored in the
Headersproperty and can be accessed through this property.
The following example shows how to access HTTP-specific properties, in this case, to turn off HTTP
keep-aliveBehavior and gets the protocol version number from the WEB server.
[C #]
(HttpWebRequest) WebRequest.Create ("http://www.contoso.com");
Turn off connection keep-alives.
Httpwreq.keepalive = false;
HttpWebResponse Httpwresp = (HttpWebResponse) httpwreq.getresponse ();
Get the HTTP protocol version number returned by the server.
String ver = HttpWResp.ProtocolVersion.ToString ();
Httpwresp.close ();
HttpWebRequestIs
WebRequestThe default class used, which is not required to register it to pass the URI to the
WebRequest.CreateMethod.
You can set the AllowAutoRedirect property to
true(the default value) enables the application to automatically follow HTTP redirection. The application redirects the request, and the
HttpWebResponseResponseUri property will contain the actual WEB resource in response to the request. If you would
AllowAutoRedirectSet to
false, the application must be able to handle redirection as an HTTP protocol error.
The application receives HTTP protocol errors by capturing the Status set to WebExceptionStatus.ProtocolError WebException. The Response property contains a message sent by the server
WebResponse, and indicates the actual HTTP error encountered.