0

I'm trying to get a "simple" Tcp Server working using Async/Await. The goal is to use TcpListener that will listen for client connections and then process asynchronously and non-blocking both read and writes for all connected clients.

What I have so far accepts connections, however what I'm seeing is the first connected client I can see the message it sends, and the messages that are received. The second and subsequent clients seemed to be blocked by the first client. I have the following code.

Do I need to use Task.Run() on the ListenerLoop() and maybe on the ReadLoop()?

Start

    public async Task Start()
    {
        _cancellationToken = new CancellationTokenSource();
        _listener.Start();

        await ListenerLoop();
    }

ListenerLoop

    public async Task ListenerLoop()
    {
        var lingerOption = new LingerOption(true, 0);
        while (!_cancellationToken.IsCancellationRequested)
        {


            var client = await _listener.AcceptTcpClientAsync();
            client.LingerState = lingerOption;
            _tcpServer.FireClientConnected(_tcpServer, client);

            await ReadLoop(client);
        }
    }

ReadLoop

    public async Task ReadLoop(TcpClient client)
    {
        var delimiter = _tcpServer.Delimiter;
        var queuedMsg = new List<byte>();
        while (!_cancellationToken.IsCancellationRequested)
        {


            if (!IsSocketConnected(client.Client))
            {

                _tcpServer.FireClientDisconnected(_tcpServer, client);
                client.GetStream().Close();
                client.Close();

                break;
            }

            var bytesAvailable = client.Available;
            if (bytesAvailable == 0) continue;

            var bytesReceived = new List<byte>();

            while (client.Available > 0 && client.Connected)
            {

                var nextByte = new byte[1];
                await client.GetStream().ReadAsync(nextByte, 0, 1, _cancellationToken.Token);
                bytesReceived.AddRange(nextByte);

                if (nextByte[0] == delimiter)
                {
                    var msg = Encoding.ASCII.GetString(queuedMsg.ToArray()) ;
                    _tcpServer.FireMessageReceived(_tcpServer, client, msg);


                    queuedMsg.Clear();
                    bytesReceived.Clear();

                }
                else
                {
                    queuedMsg.AddRange(nextByte);
                }
            }

            if (bytesReceived.Count > 0)
            {
                var msg = Encoding.ASCII.GetString(queuedMsg.ToArray());
                _tcpServer.FireMessageReceived(_tcpServer, client, msg);
            }


        }
    }
fossilz
  • 337
  • 4
  • 17

0 Answers0