title: How do I "flush" a TCP Client Buffer?
body: <p>I've pulled from several examples to setup a Full Duplex C# TCP Client connected to a server.  The basic concept is that the client and server both send/receive messages (commands and events).   Therefore, I've developed a FullDuplexSocket class that exposes a Send method to send messages to the server and a event handler to receive messages from the server.    Everything works except I can't seem to flush the buffer of messages received from the server.  Each time the server sends a new message, the buffer in my socket contains all the old messages (already read) <em>and</em> the new message(s).   I could split the messages by a known delimiter (/r/n) and keep track of them, but this will likely be the source of memory issues on long running communications. [Edit:  Updated the code to a solution that no longer has buffer issues and works correctly].</p>
  
  <p>Does anyone have any suggestions.  Total rewrite???  Code is below in hope that it will help others.</p>
  
  <p>Here's the FullDuplexSocket class:</p>
  
  <pre><code>using System;
  using System.Text;
  using System.Net.Sockets;
  
  namespace Utilities
  {
      public class StateObject{
          public Socket workSocket = null;
          public const int BUFFER_SIZE = 1024;
          public byte[] buffer = new byte[BUFFER_SIZE];
      }
  
      public class FullDuplexSocket : IDisposable
      {
          public event NewMessageHandler OnMessageReceived;
          public delegate void NewMessageHandler(string Message);
          public event DisconnectHandler OnDisconnect;
          public delegate void DisconnectHandler(string Reason);
  
          private Socket _socket;
          private bool _useASCII = true;
          private string _remoteServerIp = "";
          private int _port = 0;
  
          /// &lt;summary&gt;
          /// Constructer of a full duplex client socket.   The consumer should immedately define 
          /// and event handler for the OnMessageReceived event after construction has completed.
          /// &lt;/summary&gt;
          /// &lt;param name="RemoteServerIp"&gt;The remote Ip address of the server.&lt;/param&gt;
          /// &lt;param name="Port"&gt;The port that will used to transfer/receive messages to/from the remote IP.&lt;/param&gt;
          /// &lt;param name="UseASCII"&gt;The character type to encode/decode messages.  Defaulted to use ASCII, but setting the value to false will encode/decode messages in UNICODE.&lt;/param&gt;
          public FullDuplexSocket(string RemoteServerIp, int Port, bool UseASCII = true)
          {
              _useASCII = UseASCII;
              _remoteServerIp = RemoteServerIp;
              _port = Port;
  
              try //to create the socket and connect
              {
                  _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                  _socket.Connect(RemoteServerIp, _port);
              }
              catch (Exception e)
              {
                  throw new Exception("Unable to connect to the remote Ip.", e);
              }
  
              try //to listen to the socket
              {
                  StateObject stateObject = new StateObject();
                  stateObject.workSocket = _socket;
  
                  _socket.BeginReceive
                      (
                          stateObject.buffer, //Buffer to load in our state object
                          0, //Start at the first position in the byte array
                          StateObject.BUFFER_SIZE, //only load up to the max per read
                          0, //Set socket flags here if necessary 
                          new AsyncCallback(ReadFromSocket), //Who to call when data arrives
                          stateObject //state object to use when data arrives
                      );
              }
              catch (Exception e)
              {
                  throw new Exception("Unable to start listening to the socket.", e);
              }
          }
  
  
          /// &lt;summary&gt;
          /// This will read the bytes from the socket, convert the bytes to a string and fire the OnMessageReceived event.
          /// If the socket is forcibly closed, the OnDisconnect event will be fired.   This happens when the other side of
          /// the socket connection on the remote Ip is no longer available.
          /// &lt;/summary&gt;
          /// &lt;param name="asyncResult"&gt;&lt;/param&gt;
          public void ReadFromSocket(IAsyncResult asyncResult)
          {
              StateObject stateObject = (StateObject)asyncResult.AsyncState; //pull out the state object
              int bytesReceived = 0;
  
              try //to receive the message.
              {
                  bytesReceived = stateObject.workSocket.EndReceive(asyncResult); 
              }
              catch (Exception e)  //Exception will occur if connection was forcibly closed.
              {
                  RaiseOnDisconnect(e.Message);
                  return;
              }
  
              if (bytesReceived &gt; 0)
              {
                  RaiseOnMessageReceived
                      (
                          _useASCII ?
                              Encoding.ASCII.GetString(stateObject.buffer, 0, bytesReceived) :
                              Encoding.Unicode.GetString(stateObject.buffer, 0, bytesReceived)
                      );
  
                  stateObject.workSocket.BeginReceive
                      (
                          stateObject.buffer, //Buffer to load in our state object
                          0, //Start at the first position in the byte array
                          StateObject.BUFFER_SIZE, //only load up to the max per read
                          0, //Set socket flags here if necessary 
                          new AsyncCallback(ReadFromSocket), //Who to call when data arrives
                          stateObject //state object to use when data arrives
                      );
  
              }
              else
              {
                  stateObject.workSocket.Close();
                  RaiseOnDisconnect("Socket closed normally.");
                  return;
              }
          }
          /// &lt;summary&gt;
          /// Broadcast a message to the IP/Port.  Consumer should handle any exceptions thrown by the socket.
          /// &lt;/summary&gt;
          /// &lt;param name="Message"&gt;The message to be sent will be encoded using the character set defined during construction.&lt;/param&gt;
          public void Send(string Message)
          {
              //all messages are terminated with /r/n
              Message += Environment.NewLine;
  
              byte[] bytesToSend = _useASCII ?
                  Encoding.ASCII.GetBytes(Message) :
                  Encoding.Unicode.GetBytes(Message);
  
              int bytesSent = _socket.Send(bytesToSend);
  
          }
  
          /// &lt;summary&gt;
          /// Clean up the socket.
          /// &lt;/summary&gt;
          void IDisposable.Dispose()
          {
              try
              {
                  _socket.Close();
                  RaiseOnDisconnect("Socket closed via Dispose method.");
              }
              catch { }
              try
              {
                  _socket.Dispose();
              }
              catch { }
          }
  
  
          /// &lt;summary&gt;
          /// This method will gracefully raise any delegated events if they exist.
          /// &lt;/summary&gt;
          /// &lt;param name="Message"&gt;&lt;/param&gt;
          private void RaiseOnMessageReceived(string Message)
          {
              try //to raise delegates
              {
                  OnMessageReceived(Message);
              }
              catch { } //when none exist ignore the Object Reference Error
          }
  
          /// &lt;summary&gt;
          /// This method will gracefully raise any delegated events if they exist.
          /// &lt;/summary&gt;
          /// &lt;param name="Message"&gt;&lt;/param&gt;
          private void RaiseOnDisconnect(string Message)
          {
              try //to raise delegates
              {
                  OnDisconnect(Message);
              }
              catch { } //when none exist ignore the Object Reference Error
          }
  
      }
  }
  </code></pre>
  
  <p>The consumer of the class would simply do the following:</p>
  
  <pre><code>using System;
  
  namespace Utilities
  {
      public class SocketConsumer
      {
          private FullDuplexSocket _fds;
  
          public Consumer()
          {
              _fds = new FullDuplexSocket("192.168.1.103", 4555);
  
              _fds.OnMessageReceived += fds_OnMessageReceived;
  
              _fds.Send("Hello World!");
          }
  
          void fds_OnMessageReceived(string Message)
          {
              Console.WriteLine("Message: {0}", Message);
          }
      }
  }
  </code></pre>
  
  <p>Any help would be great.  Thanks!</p>