3

据我了解,这些行:

var client = await listener.AcceptTcpClientAsync();

var client = listener.AcceptTcpClient();

应该以相同的方式工作,但如果我尝试打开,例如,5k 连接(不关闭它们),很快监听器(异步)要么停止响应,要么抛出异常。

有人知道可能出了什么问题吗?

示例类:

class ListenerTest
{
    static int connectionNumber = 0;
    static int port = 23456;

    public void StartListening(bool async)
    {
        var listener = new TcpListener(IPAddress.Any, port);
        listener.Start();

        if (async)
        {
            var task = HandleConnectionsAsync(listener);
            task.Wait();
        }
        else
            HandleConnections(listener);
    }

    async Task HandleConnectionsAsync(TcpListener listener)
    {
        while (true)
        {
            Console.Write("Waiting for async connection...");
            var client = await listener.AcceptTcpClientAsync();
            Console.WriteLine("OK #" + connectionNumber);
            connectionNumber++;
        }
    }

    void HandleConnections(TcpListener listener)
    {
        while (true)
        {
            Console.Write("Waiting for sync connection...");
            var client = listener.AcceptTcpClient();
            Console.WriteLine("OK #" + connectionNumber);
            connectionNumber++;
        }
    }

    public static void ConnectTest(int count)
    {
        var ep = new IPEndPoint(IPAddress.Loopback, port);
        for (var i = 0; i < count; i++)
            new TcpClient().Connect(ep);
    }
}

用法:

static void Main(string[] args)
{
    var isAsync = true;
    ThreadPool.QueueUserWorkItem(new WaitCallback(StartListening), isAsync);
    ListenerTest.ConnectTest(5000);
}

static void StartListening(object state)
{
    var my = new ListenerTest();
    my.StartListening((bool)state);
}
4

2 回答 2

4

您的测试连接被 GC 杀死,如果您“固定”连接直到测试结束 - 您将获得 5000 个连接(我刚刚复制/粘贴并修复/测试了您的代码)。重写连接测试:

    public static void ConnectTest(int count)
    {
        var ep = new IPEndPoint(IPAddress.Loopback, port);
        List<TcpClient> clients = new List<TcpClient>();
        for (var i = 0; i < count; i++)
        {
            TcpClient cl = new TcpClient();
            clients.Add(cl);
            cl.Connect(ep);
        }
    }

另请注意,在“现实世界”条件下,您需要在开始侦听器循环之前添加类似这样的内容:

ThreadPool.SetMinThreads(100, 100);

这让您的代码在“突发”连接数/网络加载下工作。我们刚刚在 linux/mono 下成功地“负载测试”了 7,5K 连接。

于 2013-11-06T17:00:09.627 回答
0

一台机器不能有 100,000 个连接。TCP/IP 的端口号只有16 位(最多 64k 端口),其中很大一部分用于(或保留)用于操作系统或各种服务。

通常,这些端口中只有 16,383 个可用于传入客户端连接,您需要与所有其他定期使用 TCP/IP 的进程共享它们。

于 2013-07-08T14:54:33.093 回答