Skip to content

Stream.Read Method blocks application

Today I needed to read some data from a NetworkStream. First I tried Stream.Read-Method but then I noticed that it blocks my program.
Sometimes it seems to be meaningful to read the reference:

The implementation will block until at least one byte of data can be read, in the event that no data is available. Read returns 0 only when there is no more data in the stream and no more is expected (such as a closed socket or end of file).

I wrote a litte example showing how to read from a NetworkStream the asynchronous way. Just in case someone else stumbles across this.

C#:
  1. using System;
  2. using System.Net;
  3. using System.Net.Sockets;
  4. using System.IO;
  5. using System.Text;
  6. using System.Threading;
  7.  
  8. namespace AsyncReadExample
  9. {
  10.    
  11.     public class State {
  12.        
  13.         const int BUFFER_SIZE = 1024;
  14.        
  15.         public byte[] Buffer;
  16.         public Stream Stream;
  17.         public String ReadResult;
  18.    
  19.         public State() {
  20.             Buffer = new byte[BUFFER_SIZE];
  21.             Stream = null;
  22.             ReadResult = String.Empty;
  23.         }     
  24.     }
  25.  
  26.     class MainClass
  27.     {
  28.        
  29.         public static ManualResetEvent terminate = new ManualResetEvent(false);
  30.  
  31.         const int BUFFER_SIZE = 1024;
  32.        
  33.         [STAThread]
  34.         static void Main(string[] args) {
  35.                        
  36.             IPAddress serverip = IPAddress.Parse("127.0.0.1");
  37.             TcpListener server = new TcpListener(serverip, 12345);
  38.             server.Start();
  39.  
  40.             TcpClient client = server.AcceptTcpClient();
  41.             NetworkStream stream = client.GetStream();
  42.            
  43.             State state = new State();
  44.             state.Stream = stream;
  45.  
  46.             // nonblocking
  47.             IAsyncResult result = stream.BeginRead(
  48.                 state.Buffer,
  49.                 0,
  50.                 BUFFER_SIZE,
  51.                 new AsyncCallback(ReadCallback),
  52.                 state
  53.             );
  54.  
  55.             // do something else here
  56.             someOtherTask();
  57.  
  58.             // Wait until all data is read
  59.             terminate.WaitOne();
  60.             Console.WriteLine(state.ReadResult);
  61.             Console.ReadLine();
  62.  
  63.             client.Close();
  64.             server.Stop();
  65.         }
  66.  
  67.         private static void ReadCallback(IAsyncResult asyncResult) {
  68.             State state = (State) asyncResult.AsyncState;
  69.             Stream stream = state.Stream;
  70.  
  71.             int read = stream.EndRead(asyncResult);
  72.             if (read> 0) {
  73.                 state.ReadResult += Encoding.ASCII.GetString(state.Buffer, 0, read);
  74.                 IAsyncResult result = stream.BeginRead(
  75.                     state.Buffer,
  76.                     0,
  77.                     BUFFER_SIZE,
  78.                     new AsyncCallback(ReadCallback),
  79.                     state
  80.                 );
  81.             }
  82.             else {
  83.                 terminate.Set();
  84.             }
  85.         }
  86.  
  87.         private static void someOtherTask() {
  88.             Console.WriteLine("some other task");
  89.         }
  90.  
  91.     }
  92. }

Categories: Programming.

Tags: , , ,

Comment Feed

No Responses (yet)



Some HTML is OK

or, reply to this post via trackback.