Using Streams on the Network

Network resources are represented in the .NET Framework as streams. By treating streams generically, the .NET Framework offers the following capabilities:

  • A common way to send and receive Web data. Whatever the actual contents of the file — HTML, XML, or anything else — your application will use Stream.Write and Stream.Read to send and receive data.

  • Compatibility with streams across the .NET Framework. Streams are used throughout the .NET Framework, which has a rich infrastructure for handling them. For example, you can modify an application that reads XML data from a FileStream to read data from a NetworkStream instead by changing only the few lines of code that initialize the stream. The major differences between the NetworkStream class and other streams are that NetworkStream is not seekable, the CanSeek property always returns false, and the Seek and Position methods throw a NotSupportedException.

  • Processing of data as it arrives. Streams provide access to data as it arrives from the network, rather than forcing your application to wait for an entire data set to be downloaded.

The System.Net.Sockets namespace contains a NetworkStream class that implements the Stream class specifically for use with network resources. Classes in the System.Net.Sockets namespace use the NetworkStream class to represent streams.

To send data to the network using the returned stream, call GetRequestStream on your WebRequest. The WebRequest will send request headers to the server; then you can send data to the network resource by calling the BeginWrite, EndWrite, or Write method on the returned stream. Some protocols, such as HTTP, may require you to set protocol-specific properties before sending data. The following code example shows how to set HTTP-specific properties for sending data. It assumes that the variable sendData contains the data to send and that the variable sendLength is the number of bytes of data to send.

HttpWebRequest request = 
   (HttpWebRequest) WebRequest.Create("");
request.Method = "POST";
request.ContentLength = sendLength;
   Stream sendStream = request.GetRequestStream();
   // Handle errors . . .

To receive data from the network, call GetResponseStream on your WebResponse. You can then read data from the network resource by calling the BeginRead, EndRead, or Read method on the returned stream.

When using streams from network resources, keep in mind the following points:

  • The CanSeek property always returns false since the NetworkStream class cannot change position in the stream. The Seek and Position methods throw a NotSupportedException.

  • When you use WebRequest and WebResponse, stream instances created by calling GetResponseStream are read-only and stream instances created by calling GetRequestStream are write-only.

  • Use the StreamReader class to make encoding easier. The following code example uses a StreamReader to read an ASCII-encoded stream from a WebResponse (the example does not show creating the request).

  • The call to GetResponse can block if network resources are not available. You should consider using an asynchronous request with the BeginGetResponse and EndGetResponse methods.

  • The call to GetRequestStream can block while the connection to the server is created. You should consider using an asynchronous request for the stream with the BeginGetRequestStream and EndGetRequestStream methods.

// Create a response object.
WebResponse response = request.GetResponse();
// Get a readable stream from the server.
StreamReader sr = 
   new StreamReader(response.GetResponseStream(), Encoding.ASCII);
// Use the stream. Remember when you are through with the stream to close it.

See Also