title: Asynchronous Socket Client/Server throwing exception (TcpClient & TcpListener)
body: <p>I am trying to write an asynchronous socket Server/Client, but I keep getting the following error:</p>
  
  <pre><code>Unable to read data from the transport connection: A blocking operation was interrupted
      by a call to WSACancelBlockingCall.
  Inner Exception: System.Net.Sockets.SocketException (0x80004005): A blocking operation
      was interrupted by a call to WSACancelBlockingCall
  at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size,
      SocketFlags socketFlags)
  at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
  </code></pre>
  
  <p>This exception it thrown in  my SockerServer class at the following line:</p>
  
  <pre><code>BytesRead = ClientStream.Read(MessageBuffer, 0, BufferSize);
  </code></pre>
  
  <p>This only occurs when the Client attempts to disconnect from the server - they appear to disconnect fine and then I get this exception.</p>
  
  <p>Here is the codez:</p>
  
  <h2>MessageHandler</h2>
  
  <p>There is a single instance of this class in the Client and one for each of the clients in the server. This is used to wrap the NetworkStream for each client so that messages can be written to it.</p>
  
  <pre><code>public class MessageHandler
  {
      private readonly ASCIIEncoding ByteEncoder = new ASCIIEncoding();
  
      private readonly NetworkStream ClientStream;
  
      public MessageHandler(NetworkStream Stream)
      {
          this.ClientStream = Stream;
      }
  
      public void Send(byte[] Message)
      {
          ClientStream.Write(Message, 0, Message.Length);
          ClientStream.Flush();
      }
  
      public void Send(string Message)
      {
          byte[] MessageBytes = ByteEncoder.GetBytes(Message);
          ClientStream.Write(MessageBytes, 0, MessageBytes.Length);
          ClientStream.Flush();
      }
  }
  </code></pre>
  
  <h2>MessageHandlerEventArgs</h2>
  
  <pre><code>public class MessageHandlerEventArgs : EventArgs
  {
      public readonly MessageHandler SocketMessage;
  
      public MessageHandlerEventArgs(MessageHandler Messages)
      {
          this.SocketMessage = Messages;
      }
  }
  </code></pre>
  
  <h2>SocketHandler (Base class for SocketServer &amp; SocketClient)</h2>
  
  <pre><code>public abstract class SocketHandler
  {
      protected const int DefaultPort = 3000;
      protected const int BufferSize = 4096;
      protected readonly Action&lt;byte[]&gt; MessageAction;
  
      public SocketHandler(Action&lt;byte[]&gt; MessageAction)
      {
          this.MessageAction = MessageAction;
          ClientConnected += OnClientConnected;
          ClientDisconnected += OnClientDisconnected;
      }
  
      protected void HandleConnection(IAsyncResult ar)
      {
          TcpClient Client = (TcpClient)ar.AsyncState;
          ThreadPool.QueueUserWorkItem((x) =&gt; HandleConnection(Client));
      }
  
      protected void HandleConnection(TcpClient NetworkClient)
      {
          try
          {
              using (NetworkStream ClientStream = NetworkClient.GetStream())
              {
                  MessageHandler Messages = new MessageHandler(ClientStream);
                  DoClientConnected(new MessageHandlerEventArgs(Messages));
                  byte[] MessageBuffer = new byte[BufferSize];
                  int BytesRead;
  
                  while (true)
                  {
                      BytesRead = 0;
                      BytesRead = ClientStream.Read(MessageBuffer, 0, BufferSize);
  
                      if (BytesRead == 0)
                      {
                          DoClientDisconnected(new MessageHandlerEventArgs(Messages));
                          break;
                      }
                      else
                      {
                          MessageAction.Invoke(MessageBuffer.ToArray());
                      }
                  }
                  NetworkClient.Close();
              }
          }
          catch (Exception ex)
          {
              Logger.ExceptionLog.AddEntry(ex, "SocketHandler.HandleConnection");
          }
      }
  
      protected abstract void OnClientConnected(object sender, MessageHandlerEventArgs e);
      protected abstract void OnClientDisconnected(object sender, MessageHandlerEventArgs e);
  
      public event EventHandler&lt;MessageHandlerEventArgs&gt; ClientConnected;
      protected void DoClientConnected(MessageHandlerEventArgs args)
      {
          if (ClientConnected != null)
          {
              ClientConnected(this, args);
          }
      }
  
      public event EventHandler&lt;MessageHandlerEventArgs&gt; ClientDisconnected;
      protected void DoClientDisconnected(MessageHandlerEventArgs args)
      {
          if (ClientDisconnected != null)
          {
              OnClientDisconnected(this, args);
          }
      }
  
      public event EventHandler StatusChanged;
      protected void DoStatusChanged()
      {
          if (StatusChanged != null)
          {
              StatusChanged(this, EventArgs.Empty);
          }
      }
  }
  </code></pre>
  
  <h2>Socket Server</h2>
  
  <pre><code>public class SocketServer : SocketHandler
  {
      private static List&lt;MessageHandler&gt; CurrentClients = new List&lt;MessageHandler&gt;();
      private ServerStatus _Status;
      public ServerStatus Status
      {
          get { return _Status; }
          private set
          {
              _Status = value;
              DoStatusChanged();
          }
      }
  
      private readonly TcpListener NetworkServer;
  
      public SocketServer(Action&lt;byte[]&gt; MessageAction)
          : base(MessageAction)
      {
          NetworkServer = new TcpListener(IPAddress.Any, DefaultPort);
      }
  
      public void Start()
      {
          try
          {
              if (Status == ServerStatus.Stopped)
              {
                  ThreadPool.QueueUserWorkItem((x) =&gt; ListenForClient());
                  Status = ServerStatus.Started;
              }
          }
          catch (Exception ex)
          {
              Logger.ExceptionLog.AddEntry(ex, "SocketServer.Start");
          }
      }
  
      public void Stop()
      {
          try
          {
              if (Status != ServerStatus.Stopped)
              {
                  Status = ServerStatus.Stopped;
                  NetworkServer.Stop();
              }
          }
          catch (Exception ex)
          {
              Logger.ExceptionLog.AddEntry(ex, "SocketServer.Stop");
          }
      }
  
      private void ListenForClient()
      {
          try
          {
  
              Status = ServerStatus.WaitingClient;
              NetworkServer.Start();
              while (Status != ServerStatus.Stopped)
              {
                  if (!NetworkServer.Pending())
                  {
                      Thread.Sleep(100);
                      continue;
                  }
                  else
                  {
                      TcpClient NetworkClient = NetworkServer.AcceptTcpClient();
                      ThreadPool.QueueUserWorkItem((x) =&gt; HandleConnection(NetworkClient));
                      Status = ServerStatus.Connected;
                  }
              }
          }
          catch (Exception ex)
          {
              Logger.ExceptionLog.AddEntry(ex, "SocketServer.ListenForClient");
          }
      }
  
      protected override void OnClientConnected(object sender, MessageHandlerEventArgs e)
      {
          CurrentClients.Add(e.SocketMessage);
      }
  
      protected override void OnClientDisconnected(object sender, MessageHandlerEventArgs e)
      {
          CurrentClients.Remove(e.SocketMessage);
  
          Status = (CurrentClients.Count == 0)
              ? ServerStatus.WaitingClient
              : ServerStatus.Connected;
      }
  }
  </code></pre>
  
  <h2>SocketClient</h2>
  
  <pre><code>public class SocketClient : SocketHandler
  {
      private ClientStatus _Status;
      public ClientStatus Status
      {
          get { return _Status; }
          set
          {
              _Status = value;
              DoStatusChanged();
          }
      }
  
      private TcpClient NetworkClient;
  
      public MessageHandler Messages;
  
      public SocketClient(Action&lt;byte[]&gt; MessageAction)
          : base(MessageAction)
      {
          NetworkClient = new TcpClient();
      }
  
      public void Connect(IPAddress ServerAddress, int ServerPort)
      {
          try
          {
              if (Status == ClientStatus.Disconnected)
              {
                  Status = ClientStatus.Connecting;
                  NetworkClient.Connect(ServerAddress, ServerPort);
                  ThreadPool.QueueUserWorkItem((x) =&gt; HandleConnection(NetworkClient));
              }
          }
          catch (Exception ex)
          {
              Logger.ExceptionLog.AddEntry(ex, "SocketClient.Connect");
          }
      }
  
      public void Disconnect()
      {
          try
          {
              if (Status != ClientStatus.Disconnected)
              {
                  Status = ClientStatus.Disconnecting;
                  NetworkClient.Close();
                  Status = ClientStatus.Disconnected;
              }
          }
          catch (Exception ex)
          {
              Logger.ExceptionLog.AddEntry(ex, "SocketClient.Disconnect");
          }
  
      }
  
      protected override void OnClientConnected(object sender, MessageHandlerEventArgs e)
      {
          Messages = e.SocketMessage;
          Status = ClientStatus.Connected;
      }
  
      protected override void OnClientDisconnected(object sender, MessageHandlerEventArgs e)
      {
          Messages = null;
          Status = ClientStatus.Disconnected;
      }
  }
  </code></pre>