TcpListener - >接受并处理多个TcpClient连接(异步/等待)

时间:2017-09-26 13:47:35

标签: c# asynchronous async-await tcplistener

我想要一个简单的" Tcp Server使用Async / Await工作。目标是使用TcpListener来监听客户端连接,然后异步处理并且不阻塞所有连接客户端的读取和写入。

到目前为止,我所接受的是连接,但我所看到的是第一个连接的客户端,我可以看到它发送的消息,以及收到的消息。第二个及后续客户似乎被第一个客户阻止。我有以下代码。

我是否需要在ListenerLoop()上使用Task.Run(),也许在ReadLoop()上使用?

开始

    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);
            }


        }
    }

0 个答案:

没有答案