title: Server doesn't remove client from list
body: <p>I have a client-server applications.<br>
  The server can handle multiple client connections.</p>
  
  <p>When I click the <code>Close</code> button in the client, I expect it to be disconnected, and removed from the list of clients in the server form.</p>
  
  <p>However, it enters an infinite loop, which causes the client to be removed from the form's <code>ListView</code>, and then added again to the form's <code>ListView</code>.</p>
  
  <p>Here is my code:</p>
  
  <p><strong>RemoteBatcherClientForm</strong>:</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.Data;
  using System.Drawing;
  using System.Linq;
  using System.Text;
  using System.Windows.Forms;
  using System.Net;
  using System.Net.Sockets;
  
  namespace RemoteBatcherClient
  {
      public partial class RemoteBatcherClientForm : Form
      {
          Socket clientSock;
  
          public RemoteBatcherClientForm()
          {
              InitializeComponent();
              clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
          }
  
          private void connectBtn_Click(object sender, EventArgs e)
          {
              clientSock.Connect("127.0.0.1", 8);
              MessageBox.Show("Connected");
          }
  
          private void sendBtn_Click(object sender, EventArgs e)
          {
              if (clientSock.Send(Encoding.Default.GetBytes(txtMsg.Text)) &gt; 0)
              {
                  MessageBox.Show("Data Sent");
              }
          }
  
          private void closeBtn_Click(object sender, EventArgs e)
          {
              clientSock.Close();
              clientSock.Dispose();
              Close();
          }
      }
  }
  </code></pre>
  
  <p><strong>RemoteBatcherServer</strong>:</p>
  
  <p>Client.cs:</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.Net;
  using System.Net.Sockets;
  
  namespace RemoteBatcherServer
  {
      class Client
      {
          public string ID
          {
              get;
              private set;
          }
  
          public IPEndPoint EndPoint
          {
              get;
              private set;
          }
  
          Socket serverSock;
  
          public Client(Socket accepted)
          {
              serverSock = accepted;
  
              ID = Guid.NewGuid().ToString();
              EndPoint = (IPEndPoint)serverSock.RemoteEndPoint;
              serverSock.BeginReceive(new byte[] { 0 }, 0, 0, 0, callback, null);
          }
  
          void callback(IAsyncResult ar)
          {
              try
              {
                  serverSock.EndReceive(ar);
  
                  byte[] receiveBuffer = new byte[8192];
  
                  int rec = serverSock.Receive(receiveBuffer, receiveBuffer.Length, 0);
  
                  if (rec &lt; receiveBuffer.Length)
                  {
                      Array.Resize&lt;byte&gt;(ref receiveBuffer, rec);
                  }
  
                   if (Receieved != null)
                  {
                      Receieved(this, receiveBuffer);
                  }
  
                  serverSock.BeginReceive(new byte [] {0}, 0, 0, 0, callback, null);
              }
              catch (System.Exception ex)
              {
                  Console.WriteLine(ex.Message);
                  Close();
  
                  if (Disconnected != null)
                  {
                      Disconnected(this);
                  }
              }
          }
  
          public void Close()
          {
              serverSock.Close();
              serverSock.Dispose();
          }
  
          public delegate void ClientReceievedHandler(Client sender, byte[] data);
          public delegate void ClientDisconnectedHandler(Client sender);
  
          public event ClientReceievedHandler Receieved;
          public event ClientDisconnectedHandler Disconnected;
      }
  }
  </code></pre>
  
  <p>Listener.cs:</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.Net;
  using System.Net.Sockets;
  
  namespace RemoteBatcherServer
  {
      class Listener
      {
          Socket sck;
  
          public bool Listening
          {
              get;
              private set;
          }
  
          public int Port
          {
              get;
              private set;
          }
  
          public Listener(int port)
          {
              Port = port;
              sck = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
          }
  
          public void Start()
          {
              if (Listening)
                  return;
  
              sck.Bind(new IPEndPoint(0, Port));
              sck.Listen(0);
  
              sck.BeginAccept(callback, null);
  
              Listening = true;
          }
  
          public void Stop()
          {
              if (!Listening)
                  return;
  
              sck.Close();
              sck.Dispose();
              sck = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
          }
  
          void callback(IAsyncResult ar)
          {
              try
              {
                  Socket acceptSocket = sck.EndAccept(ar);
  
                  if (SockeetAccepted != null)
                  {
                      SockeetAccepted(acceptSocket);
                  }
  
                  sck.BeginAccept(callback, null);
              }
              catch (System.Exception ex)
              {
                  Console.WriteLine(ex.Message);
              }
          }
  
          public delegate void SocketAcceptHandler(Socket acceptSocket);
          public event SocketAcceptHandler SockeetAccepted;
      }
  }
  </code></pre>
  
  <p>RemoteBatcherServerForm.cs:</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.Data;
  using System.Drawing;
  using System.Linq;
  using System.Text;
  using System.Windows.Forms;
  using System.Net;
  using System.Net.Sockets;
  
  namespace RemoteBatcherServer
  {
      public partial class RemoteBatcherServerForm : Form
      {
          Listener listener;
  
          public RemoteBatcherServerForm()
          {
              InitializeComponent();
              listener = new Listener(8);
              listener.SockeetAccepted += new Listener.SocketAcceptHandler(listenerSocketAccepted);
  
              Load += new EventHandler(MainLoad);
          }
  
          void MainLoad(object sender, EventArgs e)
          {
              listener.Start();
          }
  
          void listenerSocketAccepted(Socket socket)
          {
              Client client = new Client(socket);
              client.Receieved += new Client.ClientReceievedHandler(clientReceived);
              client.Disconnected += new Client.ClientDisconnectedHandler(clientDisconnected);
  
              Invoke((MethodInvoker)delegate
              {
                  ListViewItem item = new ListViewItem();
                  item.Text = client.EndPoint.ToString();
                  item.SubItems.Add(client.ID);
                  item.SubItems.Add("XX");
                  item.SubItems.Add("XX");
                  item.Tag = client;
                  lstClients.Items.Add(item);
              });
          }
  
          void clientReceived(Client sender, byte[] data)
          {
              Invoke((MethodInvoker)delegate
              {
                  for (int i = 0; i &lt; lstClients.Items.Count; i++)
                  {
                      Client client = lstClients.Items[i].Tag as Client;
  
                      if (client.ID == sender.ID)
                      {
                          lstClients.Items[i].SubItems[2].Text = Encoding.Default.GetString(data);
                          lstClients.Items[i].SubItems[3].Text = DateTime.Now.ToString();
                          break;
                      }
                  }
              });
          }
  
          void clientDisconnected(Client sender)
          {
              Invoke((MethodInvoker)delegate
              {
                  for (int i = 0; i &lt; lstClients.Items.Count; i++)
                  {
                      Client client = lstClients.Items[i].Tag as Client;
  
                      if (client.ID == sender.ID)
                      {
                          lstClients.Items.RemoveAt(i);
                          break;
                      }
                  }
              });
          }       
      }
  }
  </code></pre>
  
  <p>Any ideas?</p>