title: Allow hundreds of TCP clients to connect within a second or two
body: <p>So with my software, I send a discover broadcast on the network and every "client" that receives that broadcast will connect over TCP to me. With what I have, it seems to work "OK" but I feel like there has to be a better way. What I am seeing is that some TCP connections into my software are refused (I think) because I am currently working on accepting another socket. So with my current version, I can accept a socket around 80% of the time. Sometimes more, but usually around the 80% range. The rest are refused by my software and I dont know why. To me thats unacceptable but I am suck as to improve this number.</p>
  
  <p>Here is a class I use to accept TCP clients and notify my other class about a new socket that has connected:</p>
  
  <pre><code>public class AsynchronousSocketListener
  {
      // Thread signal.
      public ManualResetEvent allDone = new ManualResetEvent(false);
      public event EventHandler&lt;ErtdRawDataArgs&gt; ClientConnected;
  
      private string bindingIp;
      public string AddressBind 
      {
          get { return this.bindingIp; } 
          private set { this.bindingIp = value; } 
      }
  
      private int port;
      public int Port
      {
          get { return this.port; }
          private set { this.port = value; }
      }
  
      private Socket listener;
  
      public AsynchronousSocketListener(string bindingIp, int port) 
      {
          this.bindingIp = bindingIp;
          this.port = port;
      }
  
      protected void OnClientConnected(string data, IPEndPoint clientEP)
      {
          if (this.ClientConnected == null)
              return;
  
          Task.Factory.StartNew(() =&gt;
          {
              //build args
              ErtdRawDataArgs args = new ErtdRawDataArgs(Encoding.Default.GetBytes(data));
              args.Source = string.Format("{0}:{1}", clientEP.Address.ToString(), clientEP.Port);
              this.ClientConnected(this, args);
          });
      }
  
      public void Close()
      {
          if (this.listener == null || !this.listener.Connected)
              return;
  
          this.listener.Shutdown(SocketShutdown.Both);
          this.listener.Close();
      }
  
      public void StartListening() 
      {
          Task.Factory.StartNew(() =&gt;
          {
              // Data buffer for incoming data.
              byte[] bytes = new Byte[1024];
  
              // Establish the local endpoint for the socket.
              IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse(this.bindingIp), this.port);
  
              // Create a TCP/IP socket.
              listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  
              // Bind the socket to the local endpoint and listen for incoming connections.
              try
              {
                  listener.Bind(localEndPoint);
                  int maxConnections = (int)SocketOptionName.MaxConnections;
                  listener.Listen(maxConnections);
  
                  while (true)
                  {
                      // Set the event to nonsignaled state.
                      allDone.Reset();
  
                      // Start an asynchronous socket to listen for connections.
                      listener.BeginAccept(
                          new AsyncCallback(AcceptCallback),
                          listener);
  
                      // Wait until a connection is made before continuing.
                      allDone.WaitOne();
                  }
  
              }
              catch (Exception e)
              {
                  Console.WriteLine(e.ToString());
              }
          });
      }
  
      public void AcceptCallback(IAsyncResult ar) 
      {
          // Signal the main thread to continue.
          allDone.Set();
  
          // Get the socket that handles the client request.
          Socket listener = (Socket) ar.AsyncState;
          Socket handler = listener.EndAccept(ar);
  
          // Create the state object.
          StateObject state = new StateObject();
          state.workSocket = handler;
          handler.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0,
              new AsyncCallback(ReadCallback), state);
      }
  
      public void ReadCallback(IAsyncResult ar) 
      {
          String content = String.Empty;
  
          // Retrieve the state object and the handler socket
          // from the asynchronous state object.
          StateObject state = (StateObject) ar.AsyncState;
          Socket handler = state.workSocket;
  
          // Read data from the client socket. 
          int bytesRead = handler.EndReceive(ar);
  
          if (bytesRead &gt; 0) {
              // There  might be more data, so store the data received so far.
              state.sb.Append(Encoding.ASCII.GetString(
                  state.buffer,0,bytesRead));
  
              // Check for end-of-file tag. If it is not there, read 
              // more data.
              content = state.sb.ToString();
              OnClientConnected(content, handler.RemoteEndPoint as IPEndPoint);
  
              //close socket
              handler.Shutdown(SocketShutdown.Both);
              handler.Close();
          }
      }
  }
  </code></pre>
  
  <p>Is there any way to improve this code or is there something completely different all together to improve my results of accepting TCP connections at about the same time?</p>