我想要一个简单的" 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);
}
}
}