title: TCP/.NET: Reading length prefixed buffer or fixed buffer size
body: <p>I'm currently in the progress of writing my own TCP network library in C# and I want to make sure I'm doing things right.</p>
  <p>Currently, I have every packet that gets sent through a socket prefixed with the length. The receiving end will read 4 bytes, convert that to an int, and read that many bytes afterward.</p>
  <p>I'm not sure if that's the best approach. Would it be better to just read a fixed amount of bytes and process from there?<br />
  In the end, I would just extract 4 bytes from the fixed length buffer and read ahead however much I need.</p>
  <p>Here is the code that I currently have to demonstrate my thought process.</p>
  <pre class="lang-cs prettyprint-override"><code>internal void BeginReceive()
  {
      ReceiveImpl();
  }
  
  protected virtual void ReceiveImpl()
  {
      // Should we rather receive a bigger buffer (e.g. 8KB) immediately and then grab the length from that?
      // It would require an internal buffer to store whatever we've already read ahead.
      var recvState = new ReceiveState(new byte[4]);
      Socket.BeginReceive(recvState.Buffer, 0, 4, SocketFlags.None, OnReceiveLength, recvState);
  }
  
  private void OnReceiveLength(IAsyncResult ar)
  {
      var recvState = (ar.AsyncState as ReceiveState)!;
      var bytesRead = Socket.EndReceive(ar, out var errorCode);
  
      if (errorCode != SocketError.Success)
      {
          // we ain't good fam!
          return;
      }
  
      if (bytesRead &gt; 0) // should we rather check if we read the 4 bytes we wanted?
      {
          var length = LengthFromBuffer(recvState.Buffer);
          recvState.Buffer = new byte[length];
  #if DEBUG
          Console.WriteLine($&quot;Receiving a packet with length of {length}.&quot;);
  #endif
          // what if the packet is absolutely massive? should we limit the buffer size?
          Socket.BeginReceive(recvState.Buffer, 0, length, SocketFlags.None, OnReceive, recvState);
      }
  }
  
  private void OnReceive(IAsyncResult ar)
  {
      var recvState = (ar.AsyncState as ReceiveState)!;
      var bytesRead = Socket.EndReceive(ar, out var errorCode);
  
      if (errorCode != SocketError.Success)
      {
          // we ain't good fam!
          return;
      }
  
      if (bytesRead &gt; 0)
      {
          recvState.BytesReceived += bytesRead;
          if (recvState.BytesReceived &lt; recvState.Buffer.Length)
          {
              Socket.BeginReceive(recvState.Buffer, recvState.BytesReceived,
                  recvState.Buffer.Length - recvState.BytesReceived, SocketFlags.None, OnReceive, recvState);
              return;
          }
  
          OnDataReceived(recvState.Buffer); // this will call BeginReceive again.
      }
  }
  </code></pre>