为什么异步客户端TCP操作似乎表现得比同步TCP操作差?

时间:2018-08-09 19:03:24

标签: c# sockets tcp async-await tcpclient

我已经使用SocketAsyncEventArgs用C#编写了高性能的TCP服务器。我一直在用两个非常简单的客户端测试它们的性能,每个客户端创建2000个并行连续循环。一个客户端使用对TcpClient的异步调用;另一个利用同步调用。

异步

Parallel.For(0, numClients, parallelOptions, async i =>
{
    while (true)
    {
        var tcpClient = new TcpClient();

        try
        {
            await tcpClient.ConnectAsync(host, port);

            await tcpClient.GetStream().WriteAsync(message);

            var buffer = new byte[1024];
            await tcpClient.GetStream().ReadAsync(buffer, 0, 1024);

            tcpClient.GetStream().Close();
        }
        catch (Exception ex)
        {
            Console.WriteLine($"{DateTime.Now.ToLongTimeString()}: {ex.Message}");
        }
        finally
        {
            tcpClient.Close();
            tcpClient.Dispose();
        }
    }
});

同步

Parallel.For(0, numClients, parallelOptions, i =>
{
    while (true)
    {
        var tcpClient = new TcpClient();

        try
        {
            tcpClient.Connect(host, port);

            tcpClient.GetStream().Write(message);

            var buffer = new byte[1024];
            tcpClient.GetStream().Read(buffer, 0, 1024);

            tcpClient.GetStream().Close();
        }
        catch (Exception ex)
        {
            Console.WriteLine($"{DateTime.Now.ToLongTimeString()}: {ex.Message}");
        }
        finally
        {
            tcpClient.Close();
            tcpClient.Dispose();
        }
    }
});

同步版本不断迭代,没有任何错误。

但是,异步版本会导致许多No connection could be made because the target machine actively refused it错误。我的假设是此客户端正在泛滥TCP侦听积压队列,从而导致后续的入站连接被拒绝。

这是怎么回事?如何保护服务器吞吐量免受选择异步连接的客户端的影响?

1 个答案:

答案 0 :(得分:0)

Parallel.For用于等待循环中所有任务的完成。但是,在异步调用的情况下,循环委托会立即完成,并返回内部异步调用的承诺。但是,外面的“没人”会等待此诺言完成,因为Parallel.For并不是为Parallel.For设计的,因此会导致当ConnectAsync快速触发只能启动第一个异步操作的任务时(是 "webpack": "^4.17.1" "json-loader": "^0.5.7", ),这很可能导致SYN泛洪。但是,由于尚未等待异步操作,还会导致其他副作用。