title: C# Begin/EndReceive - how do I read large data?
body: <p>When reading data in chunks of say, 1024, how do I continue to read from a socket that receives a message bigger than 1024 bytes until there is no data left? Should I just use BeginReceive to read a packet's length prefix only, and then once that is retrieved, use Receive() (in the async thread) to read the rest of the packet? Or is there another way?</p>
  <h2>edit:</h2>
  <p>I thought Jon Skeet's link had the solution, but there is a bit of a speedbump with that code. The code I used is:</p>
  <pre><code>public class StateObject
  {
      public Socket workSocket = null;
      public const int BUFFER_SIZE = 1024;
      public byte[] buffer = new byte[BUFFER_SIZE];
      public StringBuilder sb = new StringBuilder();
  }
  
  public static void Read_Callback(IAsyncResult ar)
  {
      StateObject so = (StateObject) ar.AsyncState;
      Socket s = so.workSocket;
      
      int read = s.EndReceive(ar);
      
      if (read &gt; 0) 
      {
          so.sb.Append(Encoding.ASCII.GetString(so.buffer, 0, read));
  
          if (read == StateObject.BUFFER_SIZE)
          {
              s.BeginReceive(so.buffer, 0, StateObject.BUFFER_SIZE, 0, 
                      new AyncCallback(Async_Send_Receive.Read_Callback), so);
              return;
          }
      }
      
      if (so.sb.Length &gt; 0)
      {
          //All of the data has been read, so displays it to the console
          string strContent;
          strContent = so.sb.ToString();
          Console.WriteLine(String.Format(&quot;Read {0} byte from socket&quot; + 
          &quot;data = {1} &quot;, strContent.Length, strContent));
      }
      s.Close();
  }
  </code></pre>
  <p>Now this corrected works fine most of the time, but it fails when <em>the packet's size is a multiple of the buffer</em>. The reason for this is if the buffer gets filled on a read it is assumed there is more data; but the same problem happens as before. A 2 byte buffer, for exmaple, gets filled twice on a 4 byte packet, and assumes there is more data. It then blocks because there is nothing left to read. <strong>The problem is that the receive function doesn't know when the end of the packet is.</strong></p>
  <hr />
  <p>This got me thinking to two possible solutions: I could either have an end-of-packet delimiter or I could read the packet header to find the length and then receive exactly that amount (as I originally suggested).</p>
  <p>There's problems with each of these, though. I don't like the idea of using a delimiter, as a user could somehow work that into a packet in an input string from the app and screw it up. It also just seems kinda sloppy to me.</p>
  <p>The length header sounds ok, but I'm planning on using protocol buffers - I don't know the format of the data. Is there a length header? How many bytes is it? Would this be something I implement myself? Etc..</p>
  <p>What should I do?</p>