Библиотека сайта rus-linux.net
Сервер TCP/IP ... много серверов хороших и разных
Олег И.Цилюрик
Ремейк 2.08 от 30.04.2012 г. статьи, опубликованной в 2003 году.
Оглавление
- История вопроса
- Постановка задачи
- Клиент
- Варианты серверов
- Простой последовательный сервер
- Классический параллельный сервер
- Сервер с предварительным созданием копий процесса
- Сервер активируемый суперсервером (xinetd)
- Параллельный сервер, создающий потоки по запросам
- Сервер с предварительным созданием потоков
- Оптимальное управление потоками (пул)
- Последовательный сервер с очередью обслуживания
- В качестве итогов...
История вопроса
Первоначально (июнь 2003г.) эта публикация была отработана в операционной системе QNX (версия 6.1) и подготовлена для публикации в журнале «СТА» [1], позже (июнь 2004г.) она вошла в книгу [2]. За прошедшие 10 лет ко мне неоднократно обращались с вопросами, замечаниями и за советом в связи с этим текстом. Оказалось, что и операционная система QNX несколько утратила свою актуальность, и многие публикации того времени выглядят не интересными, а вопрос систематизации техник программирования серверов не утратил своей актуальности. Но, когда возникла возможность заново опубликовать эту статью уже относительно Linux, оказалось, что в Linux достаточно многие вещи нужно поменять (хоть и по мелочам). Из-за этого, предлагается не прежняя версия текста, а новая, переписанная «по мотивам», поэтому и названная «ремейк». Ещё более поменялись примеры иллюстрирующих кодов. Я беру за основу для переписывания исходный (старый) текст как он есть, пусть даже текст при том может выглядеть, местами, достаточно несуразно... Но исходной установкой было: осовременить существующий текст: сравнить как было и как стало (через 10 лет).
Постановка задачи
Зачастую, если это не приходится делать вам очень часто (не является основной спецификой работы), при необходимости написания TCP/IP сервера «по-быстренькому» используются одна из двух классических технологий: последовательный сервер, или параллельный сервер на основе fork() (Windows-программисты в этом случае пишут сервер на основе потоков). Хотя реально можно предложить гораздо больше принципиально различных серверов, которые будут существенно отличаться своей сложностью, временем реакции на запрос клиента и другими показателями. Ниже описано несколько таких способов с результатами их поверхностной оценки.
Мы напишем специальный тестовый TCP/IP клиент, который посылает требуемое число раз запрос к серверу (а сервера будут выполнять функции простого ретранслятора), принимает от него ответ, и тут же разрывает соединение (по такой примерно схеме обрабатываются запросы в HTTP протоколе). Серия запросов от клиента делается для усреднения результата и для того (как будет видно далее), чтобы исключить (или учесть, выделить) эффекты кэширования памяти. Клиент измеряет время (точнее – число тактов процессора, это высокая точность наносекундного диапазона) между отправкой запроса серверу и приходом ответа от него. Все показанные программы – предложены в упрощённых вариантах: не везде сделана полная обработка ошибочных ситуаций (что, вообще-то говоря, крайне необходимо), и сознательно не включена обработка сигнала SIGCHLD, которая должна препятствовать появлению «зомби» процессов. Все приводимые коды программ – работающие и апробированные: весь результирующий вывод скопирован непосредственно с консоли задачи. Весь приводимый программный код транслировался компилятором GCC в нотации языка C++ (хотя специфические объектные особенности С++, за исключением потокового ввода-вывода С++ и не использованы — всё то же легко выписать на классическом С, но оно выглядит несколько более объёмным, и это одна из причин выбора языка иллюстраций).
Вперед |