Типичное серверное приложение создало бы сокет для каждого входящего соединения, создавая новый поток.
Это неправда. Очень мало серверов — только те, которые не нуждаются в масштабировании для большого количества подключенных клиентов, и даже не все из них — посвятят целую цепочку одному соединению.
Я бы сказал, что только самые рудиментарные серверы будут использовать дизайн нити за соединение. Я полагаю, что, поскольку на экспериментальных серверах гораздо больше экспериментальных пользователей (т. Е. Любителей писать код сети), чем на производственных серверах, чистые числа могут быть на стороне потока за соединение.
Но IMHO только серверы производства действительно имеют отношение к вопросу, поскольку они показывают, что хорошо дизайн и реализация были бы. И для тех, нить за соединение определенно будет в меньшинстве.
Однако возможно ли сделать demuxing самостоятельно в одном потоке?
С помощью Socket.Select()
можно использовать одну цепочку, предназначенную для обработки нескольких сокетов.
Однако более типичным было бы использовать один из нескольких асинхронных API программирования, доступных для использования с сокетами, который использует порты завершения ввода-вывода для обработки обработки операций ввода-вывода в пул потоков, предназначенных для этой цели , Это позволяет использовать параллельность, но эффективно использовать потоки для минимизации контекстного переключения.
Мой предпочтительный подход с текущим .NET 4.5 и C# 5.0 особенностей является обернуть сокет в экземпляре NetworkStream
, так что я могу использовать ReadAsync()
и WriteAsync()
методы, которые, в свою очередь, позволяет использовать await
в C# код. Это упрощает чтение и реализацию асинхронного кода.
Но вы можете использовать, например. Socket.BeginReceive()
или Socket.ReceiveAsync()
(последний полезен для серверов, которым требуется чрезвычайно высокая масштабируемость и hellip, даже первая из них по-прежнему гораздо более масштабируема, чем потоковая связь).
Независимо от используемого API, типичная реализация сервера будет включать в себя класс объектов состояния для каждого соединения.Это можно сделать с помощью конструкции нить за соединение так же легко, как и с асинхронными вводами-выводами. Ваш конечный автомат будет находиться в этом классе объектов состояния, так что обработка операций ввода-вывода в сокете может использовать конечный автомат.