Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does the begin/async tcplistener work

I am creating a windows service that accepts TCP connections, processes data sent to the server, then returns back a message saying the process is complete. There are several clients that will be connecting to the service and that number is growing. To handle these messages, I thought that using a non-blocking structure would be ideal. From initial searches, the BeginAcceptTcpClient appeared to be what I was looking for. I was looking at this tutorial to get a sample, but I have a few questions on how this works. My code I have based on this example is below.

  1. In the OnClientConnected function, why is it necessary to call WaitForClients again? Why doesn't the listener just always listen?
  2. What happens if another connection is attempted before WaitForClients is called again? I know it is the first statement in the OnClientConnected, but there could be two connections that happen "at the same time"
  3. I can't really understand how this works in terms of multithreading. If I had 10 simulations connections, it looks like the first one will enter OnClientConnected, then call WaitForClients, which will then allow another connection to be handled. This seems sort of a one connection at a time approach rather than having several threads that can handle lots of traffic.

public class DeviceListener
{
    private TcpListener listener = null;

    public DeviceListener()
    {
        listener = new TcpListener(1001);
    }

    public void StartListener()
    {
        listener.Start();
        //TODO: Log listening started here
        WaitForClients();
    }

    private void WaitForClients()
    {
        listener.BeginAcceptTcpClient(OnClientConnected, null);
    }

    private void OnClientConnected(IAsyncResult asyncResult)
    {
        WaitForClients();
        TcpClient client = listener.EndAcceptTcpClient(asyncResult);

        if(client != null)
        {
            //TODO: Log connected
            HandleClientRequest(client);
        }
    }

    private void HandleClientRequest(TcpClient client)
    {
        //Code to process client request
    }
}
like image 814
Justin Avatar asked Sep 01 '25 22:09

Justin


1 Answers

  1. No, it accepts exactly as many connections as BeginAcceptTcpClient calls, so in order to accept another one you need to call BeginAcceptTcpClient again. Beginning of handler seems like a reasonable place to do so.
  2. It will be queued and handled with next call to BeginAcceptTcpClient or timed out if that doesn't happen in timely manner.
  3. Please refer to the docs, these are most likely run using ThreadPool.
like image 66
orhtej2 Avatar answered Sep 03 '25 12:09

orhtej2