Я ищу любые стратегии, которые люди используют при реализации серверных приложений, которые обслуживают клиентские запросы TCP (или UDP): шаблоны проектирования, методы реализации, лучшие практики и т. д.
Предположим для целей этого вопроса, что запросы относительно долгоживущие (несколько минут) и что трафик чувствителен ко времени, поэтому задержки при ответе на сообщения недопустимы. Кроме того, мы обслуживаем запросы от клиентов и устанавливаем собственные подключения к другим серверам.
Моя платформа - .NET, но поскольку лежащая в основе технология одинакова независимо от платформы, мне интересно получить ответы для любого языка.





Современный подход заключается в использовании операционной системы для мультиплексирования множества сетевых сокетов за вас, освобождая ваше приложение для обработки только активных соединений с трафиком.
Всякий раз, когда вы открываете сокет, он связывает его с селектором. Вы используете один поток для опроса этого селектора. Всякий раз, когда поступают данные, селектор будет указывать активный сокет, вы передаете эту операцию дочернему потоку и продолжаете опрос.
Таким образом, вам понадобится только поток для каждой параллельной операции. Открытые, но незанятые сокеты не прерывают поток.
Доброго времени суток,
Я бы начал с рассмотрения метафоры, которую вы хотите использовать для своей структуры потоков.
Может быть, «ведущий последователь», когда поток прослушивает входящие запросы, и когда приходит новый запрос, он выполняет свою работу, и следующий поток в пуле начинает прослушивать входящие запросы.
Или пул потоков, в котором один и тот же поток всегда прослушивает входящие запросы, а затем передает запросы следующему доступному потоку в пуле потоков.
Вы можете посетить раздел Реактор компонентов Ace, чтобы почерпнуть некоторые идеи.
HTH.
ваше здоровье, Роб
Более сложный подход - использовать порты завершения ввода-вывода. (Windows) С портами завершения ввода-вывода вы оставляете управление опросом операционной системе, что позволяет ей потенциально использовать очень высокий уровень оптимизации с поддержкой драйвера сетевой карты. По сути, у вас есть очередь сетевых операций, управляемая ОС, и вы предоставляете функцию обратного вызова, которая вызывается после завершения операции. Немного похоже на DMA (жесткий диск), но для сети.
Несколько лет назад на Codeproject Лен Холгейт написал эксцентричную серию статей о портах завершения ввода-вывода: http://www.codeproject.com/KB/IP/jbsocketserver2.aspx
И Я нашел статью о портах завершения ввода-вывода для .net (хотя и не читал) http://www.codeproject.com/KB/cs/managediocp.aspx
Я бы также сказал, что использовать порты завершения проще, чем пытаться написать масштабируемую альтернативу. Проблема в том, что они доступны только на NT (2000, XP, Vista).
Если вы использовали C++ и Win32 напрямую, я бы посоветовал вам прочитать о перекрывающихся портах ввода-вывода и завершения ввода-вывода. У меня есть бесплатная платформа C++, IOCP, клиент / сервер с полным исходным кодом, см. здесь для более подробной информации.
Поскольку вы используете .Net, вам следует подумать об использовании методов асинхронных сокетов, чтобы вам не нужно было иметь поток для каждого соединения; есть несколько ссылок из этого моего сообщения в блоге, которые могут быть полезными отправными точками: http://www.lenholgate.com/blog/2005/07/disappointing-net-sockets-article-in-msdn-magazine-this-month.html (некоторые из лучших ссылок находятся в комментариях к исходному сообщению!)