Асинхронный TcpListener не продолжает порождать потоки - PullRequest
0 голосов
/ 16 мая 2019

Мой вопрос об асинхронном клиент / сервер. Я хочу, чтобы на сервере работало несколько соединений одновременно, при условии, что каждое из них отправляет / получает несколько сообщений, и им приходится выполнять длительные задания (для передачи файла с клиента на сервер и наоборот). что займет около 5-10 секунд. В настоящее время мой код сервера ниже отправляет одно сообщение и читает одно сообщение, отправленное клиентом, и после этого появляется Thread.Sleep(5000), зная, что на этом месте будет моя длительная операция, выполнение которой займет несколько секунд.

Проблема в том, что когда я открываю клиент, он выполняет несколько соединений (обычно 12, вероятно, потому что у меня i7-8750H - 12 потоков) одновременно, а остальные выполняются отдельно один за другим. Вы можете увидеть это на GIF ниже. Проблема заключается в том, что при первом подключении клиента к серверу требуется 12 подключений, а затем каждое из подключений выполняется одно за другим. Я проверил это, закрыв сервер, оставив клиент открытым, а затем перезапустив сервер.

Как я могу подключить все соединения и выполнять их долговременную работу одновременно? Я понимаю, что не могу запустить более 12 потоков одновременно на своем 12-потоковом процессоре.

GIF для представления проблемы: enter image description here

Ниже приведен фрагмент кода, но вы можете найти весь код для клиента и сервера в pastebins:

// https://pastebin.com/NcA5Vja2 The entire server code
private static void AcceptCallback(IAsyncResult ar)
{
    // Signal the main thread to continue
    _mre.Set();

    TcpListener listener = (TcpListener)ar.AsyncState;
    TcpClient client = listener.EndAcceptTcpClient(ar);

    IPAddress ip = ((IPEndPoint)client.Client.RemoteEndPoint).Address;
    Console.WriteLine($"{ip} has connected!");

    // In production a SSL certificate can be added. More information here: https://docs.microsoft.com/en-us/dotnet/api/system.net.security.sslstream?redirectedfrom=MSDN&view=netframework-4.8
    using (NetworkStream ns = client.GetStream())
    {
        SendMessage(ns, "Mr. Client, hello");

        string result = ReadMessage(ns);
        Console.WriteLine(result);
    }

    Thread.Sleep(5000);

    // Close connection
    client.Close();
    Console.WriteLine($"{ip} has disconnected!");
}

// https://pastebin.com/gVKZy4N6 The entire client code
...