title: Sending data via Socket.BeginSend/EndSend isn't flushing the buffer?
body: <p>I have a class that handles communication to and from a client connected to my server. I am able to process the packets sent to me from the telnet clients without much of an issue.</p>
  
  <h3>The client connection class</h3>
  
  <pre><code>namespace Mud.Engine.Components.WindowsServer
  {
      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Net.Sockets;
      using System.Text;
      using Mud.Engine.Runtime.Game.Character;
  
      /// &lt;summary&gt;
      /// Handles the players networking state.
      /// &lt;/summary&gt;
      public sealed class PlayerConnectionState
      {
          /// &lt;summary&gt;
          /// The size of the buffer that will hold data sent from the client
          /// &lt;/summary&gt;
          private readonly int bufferSize;
  
          /// &lt;summary&gt;
          /// A temporary collection of incomplete messages sent from the client. These must be put together and processed.
          /// &lt;/summary&gt;
          private readonly List&lt;string&gt; currentData = new List&lt;string&gt;();
  
          /// &lt;summary&gt;
          /// What the last chunk of data sent from the client contained.
          /// &lt;/summary&gt;
          private string lastChunk = string.Empty;
  
          /// &lt;summary&gt;
          /// Instances a new PlayerConnectionState.
          /// &lt;/summary&gt;
          /// &lt;param name="player"&gt;An instance of a Player type that will be performing network communication&lt;/param&gt;
          /// &lt;param name="currentSocket"&gt;The Socket used to communicate with the client.&lt;/param&gt;
          /// &lt;param name="bufferSize"&gt;The storage size of the data buffer&lt;/param&gt;
          public PlayerConnectionState(IPlayer player, Socket currentSocket, int bufferSize)
          {
              this.Player = player;
              this.CurrentSocket = currentSocket;
  
              this.bufferSize = bufferSize;
              this.Buffer = new byte[bufferSize];
          }
  
          /// &lt;summary&gt;
          /// Gets the Player instance associated with this state.
          /// &lt;/summary&gt;
          public IPlayer Player { get; private set; }
  
          /// &lt;summary&gt;
          /// Gets the Socket for the player associated with this state.
          /// &lt;/summary&gt;
          public Socket CurrentSocket { get; private set; }
  
          /// &lt;summary&gt;
          /// Gets the data currently in the network buffer
          /// &lt;/summary&gt;
          public byte[] Buffer { get; private set; }
  
          /// &lt;summary&gt;
          /// Gets if the current network connection is in a valid state.
          /// &lt;/summary&gt;
          public bool IsConnectionValid
          {
              get
              {
                  return this.CurrentSocket != null &amp;&amp; this.CurrentSocket.Connected;
              }
          }
  
          /// &lt;summary&gt;
          /// Starts listening for network communication sent from the client to the server
          /// &lt;/summary&gt;
          public void StartListeningForData()
          {
              this.Buffer = new byte[bufferSize];
              this.CurrentSocket.BeginReceive(this.Buffer, 0, bufferSize, 0, new AsyncCallback(this.ReceiveData), null);
              this.Player.CommandManager.CommandCompleted += this.HandleCommandExecutionCompleted;
          }
  
          public void SendMessage(string message)
          {
              byte[] buffer = Encoding.ASCII.GetBytes(message);
              this.CurrentSocket.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(this.CompleteMessageSending), null);
          }
  
          private void CompleteMessageSending(IAsyncResult asyncResult)
          {
              this.CurrentSocket.EndSend(asyncResult);
          }
  
          private void HandleCommandExecutionCompleted(object sender, CommandCompletionArgs e)
          {
              this.SendMessage($"{e.Command} executed.\r\n");
          }
  
          /// &lt;summary&gt;
          /// Receives the input data from the user.
          /// &lt;/summary&gt;
          /// &lt;param name="result"&gt;The result.&lt;/param&gt;
          private void ReceiveData(IAsyncResult result)
          {
              // If we are no longer in a valid state, dispose of the connection.
              if (!this.IsConnectionValid)
              {
                  this.CurrentSocket?.Dispose();
                  return;
              }
  
              int bytesRead = this.CurrentSocket.EndReceive(result);
              if (bytesRead == 0 || !this.Buffer.Any())
              {
                  this.StartListeningForData();
                  return;
              }
  
              ProcessReceivedData(bytesRead);
              this.StartListeningForData();
          }
  
          /// &lt;summary&gt;
          /// Process the data we received from the client.
          /// &lt;/summary&gt;
          /// &lt;param name="bytesRead"&gt;&lt;/param&gt;
          private void ProcessReceivedData(int bytesRead)
          {
              // Encode our input string sent from the client
              this.lastChunk = Encoding.ASCII.GetString(this.Buffer, 0, bytesRead);
  
              // Temporary to avoid handling the telnet negotiations for now. 
              // This needs to be abstracted out in to a negotation class that will parse, send and receive negotiation requests.
              if (this.Buffer.First() == 255)
              {
                  return;
              }
  
              // If the previous chunk did not have a new line feed, then we add this message to the collection of currentData.
              // This lets us build a full message before processing it.
              if (!lastChunk.Contains("\r\n"))
              {
                  // Add this to our incomplete data stash and read again.
                  this.currentData.Add(lastChunk);
                  return;
              }
  
              // This message contained at least 1 new line, so we split it and process per line.
              List&lt;string&gt; messages = lastChunk.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries).ToList();
  
              foreach (string line in this.PruneReceivedMessages(messages))
              {
                  this.Player.CommandManager.ProcessCommandForCharacter(this.Player, line);
              }
          }
  
          /// &lt;summary&gt;
          /// Runs through the messages collection and prepends data from a previous, incomplete, message
          /// and updates the internal message tracking state.
          /// &lt;/summary&gt;
          /// &lt;param name="messages"&gt;&lt;/param&gt;
          private List&lt;string&gt; PruneReceivedMessages(List&lt;string&gt; messages)
          {            
              // Append the first line to the incomplete line given to us during the last pass if one exists.
              if (this.currentData.Any() &amp;&amp; messages.Any())
              {
                  messages[0] = string.Format("{0} {1}", string.Join(" ", this.currentData), messages[0]);
                  this.currentData.Clear();
              }
  
              // If we have more than 1 line and the last line in the collection does not end with a line feed
              // then we add it to our current data so it may be completed during the next pass. 
              // We then remove it from the lines collection because it can be infered that the remainder will have
              // a new line due to being split on \n.
              if (messages.Count &gt; 1 &amp;&amp; !messages.Last().EndsWith("\r\n"))
              {
                  this.currentData.Add(messages.Last());
                  messages.Remove(messages.Last());
              }
  
              return messages;
          }
      }
  }
  </code></pre>
  
  <p>The problem is really focused on the following methods:</p>
  
  <pre><code>    public void StartListeningForData()
      {
          this.Buffer = new byte[bufferSize];
          this.CurrentSocket.BeginReceive(this.Buffer, 0, bufferSize, 0, new AsyncCallback(this.ReceiveData), null);
          this.Player.CommandManager.CommandCompleted += this.HandleCommandExecutionCompleted;
      }
  
      public void SendMessage(string message)
      {
          byte[] buffer = Encoding.ASCII.GetBytes(message);
          this.CurrentSocket.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(this.CompleteMessageSending), null);
      }
  
      private void CompleteMessageSending(IAsyncResult asyncResult)
      {
          this.CurrentSocket.EndSend(asyncResult);
      }
  
      private void HandleCommandExecutionCompleted(object sender, CommandCompletionArgs e)
      {
          this.SendMessage($"{e.Command} executed.\r\n");
      }
  </code></pre>
  
  <p>When a message is processed by my stuff, it creates a new CommandCompletionArg, passes it the command string, and sends it along to the event handler. When the <code>HandleCommandExecutionCompleted</code> handler is invoked, the <code>e.Command</code> property does hold the data that I sent in via the Telnet client. I would expect to see my command echo'd back to me.</p>
  
  <p>Enter: "Hello World"
  Expected Result: "Hello World executed."
  Result: " executed."</p>
  
  <p>As I type additional commands, the additional commands are sent along with the previous command results over again. It also looks like that if I send in a command string longer than the string I am echoing back, it adds the string to the end. You can see the oddity in the screenshots, on both Windows and OS X.</p>
  
  <p>What am I doing wrong? I don't understand why when I debug, I can see that e.Command actually has data, but it never sends it back to the client. It only sends "executed".</p>
  
  <p><img src="https://i.stack.imgur.com/mepNl.png" alt="OS X">
  <img src="https://i.stack.imgur.com/jiEGQ.png" alt="Windows"></p>
  
  <p>If it helps any, the <a href="https://github.com/scionwest/muddesigner" rel="nofollow noreferrer">code is open source and available</a> to view in its entirety. You can clone it from GitHub and run the Desktop.Server.App project. The port you connect to is 5000.</p>