title: C# Socket.BeginReceive/EndReceive
body: <p>In what order is the Socket.BeginReceive/EndReceive functions called?</p>
  
  <p>For instance, I call <strong>BeginReceive</strong> twice, once to get the message length and the second time to get the message itself. Now the scenario is like that, for every message I send, I start waiting for its completion (actually acknowledgment of the message sent, also I wait for the action's completion after receiving the acknowledgment), so I call <strong>BeginReceive</strong> with each <strong>BeginSend</strong>, but in each <strong>BeginReceive</strong>'s callback, I check if I'm receiving the length or the message. If I'm receiving the message and have received it completely, then I call another <strong>BeginReceive</strong> to receive the completion of the action. Now this is where things get out of sync. Because one of my receive callback is receiving bytes which it interprets as the length of them message when in fact it is the message itself.</p>
  
  <p>Now how do I resolve it?</p>
  
  <p><strong>EDIT:</strong> This is a C#.NET question :)</p>
  
  <p>Here is the code, basically it is too big, sorry for that</p>
  
  <pre><code>public void Send(string message)
  {
      try
      {
          bytesSent = 0;
  
          writeDataBuffer = System.Text.Encoding.ASCII.GetBytes(message);
          writeDataBuffer = WrapMessage(writeDataBuffer);
          messageSendSize = writeDataBuffer.Length;
  
          clientSocket.BeginSend(writeDataBuffer, bytesSent, messageSendSize, SocketFlags.None,
                              new AsyncCallback(SendComplete), clientSocket);
      }
      catch (SocketException socketException)
      {
          MessageBox.Show(socketException.Message);
      }
  }
  
  public void WaitForData()
  {
      try
      {
          if (!messageLengthReceived)
          {
              clientSocket.BeginReceive(receiveDataBuffer, bytesReceived, MESSAGE_LENGTH_SIZE - bytesReceived,
                                      SocketFlags.None, new AsyncCallback(RecieveComplete), clientSocket);
          }
  }
  
  public void Send(string message)
  {
      try
      {
          bytesSent = 0;
  
          writeDataBuffer = System.Text.Encoding.ASCII.GetBytes(message);
          writeDataBuffer = WrapMessage(writeDataBuffer);
          messageSendSize = writeDataBuffer.Length;
  
          clientSocket.BeginSend(writeDataBuffer, bytesSent, messageSendSize, SocketFlags.None,
                              new AsyncCallback(SendComplete), clientSocket);
      }
      catch (SocketException socketException)
      {
          MessageBox.Show(socketException.Message);
      }
  }
  
  public void WaitForData()
  {
      try
      {
          if (! messageLengthReceived)
          {
              clientSocket.BeginReceive(receiveDataBuffer, bytesReceived, MESSAGE_LENGTH_SIZE - bytesReceived,
                                      SocketFlags.None, new AsyncCallback(RecieveComplete), clientSocket);
          }
          else 
          {
              clientSocket.BeginReceive(receiveDataBuffer, bytesReceived, messageLength - bytesReceived,
                                      SocketFlags.None, new AsyncCallback(RecieveComplete), clientSocket);
          }
      }
      catch (SocketException socketException)
      {
          MessageBox.Show(socketException.Message);
      }
  }
  
  public void RecieveComplete(IAsyncResult result)
  {
      try
      {
          Socket socket = result.AsyncState as Socket;
          bytesReceived = socket.EndReceive(result);
  
          if (! messageLengthReceived)
          {
              if (bytesReceived != MESSAGE_LENGTH_SIZE)
              {
                  WaitForData();
                  return;
              }
  
              // unwrap message length
              int length = BitConverter.ToInt32(receiveDataBuffer, 0);
              length = IPAddress.NetworkToHostOrder(length);
  
              messageLength = length;
              messageLengthReceived = true;
  
              bytesReceived = 0;
  
              // now wait for getting the message itself
              WaitForData();
          }
          else
          {
              if (bytesReceived != messageLength)
              {
                  WaitForData();
              }
              else
              {
                  string message = Encoding.ASCII.GetString(receiveDataBuffer);
  
                  MessageBox.Show(message);
  
                  bytesReceived = 0;
                  messageLengthReceived = false;
  
                  // clear buffer
                  receiveDataBuffer = new byte[AsyncClient.BUFFER_SIZE];
  
                  WaitForData();
              }
          }
      }
      catch (SocketException socketException)
      {
          MessageBox.Show(socketException.Message);
      }
  
  }
  
  public void SendComplete(IAsyncResult result)
  {
      try
      {
          Socket socket = result.AsyncState as Socket;
          bytesSent = socket.EndSend(result);
  
          if (bytesSent != messageSendSize)
          {
              messageSendSize -= bytesSent;
  
              socket.BeginSend(writeDataBuffer, bytesSent, messageSendSize, SocketFlags.None,
                              new AsyncCallback(SendComplete), clientSocket);
              return;
          }
  
          // wait for data
          messageLengthReceived = false;
          bytesReceived = 0;
  
          WaitForData();
      }
      catch (SocketException socketException)
      {
          MessageBox.Show(socketException.Message);
      }
  }
  </code></pre>