Шрифт:
Если мы измерим время работы нашего клиента TCP, использующего функцию
Мы еще не завершили написание нашей функции
6.8. Эхо-сервер TCP (продолжение)
Вернемся к нашему эхо-серверу TCP из разделов 5.2 и 5.3. Перепишем сервер как одиночный процесс, который будет использовать функцию
Рис. 6.11. Сервер TCP до того, как первый клиент установил соединение
У сервера имеется одиночный прослушиваемый дескриптор, показанный на рисунке точкой.
Сервер обслуживает только набор дескрипторов для чтения, который мы показываем на рис. 6.12. Предполагается, что сервер запускается в приоритетном (foreground) режиме, а дескрипторы 0, 1 и 2 соответствуют стандартным потокам ввода, вывода и ошибок. Следовательно, первым доступным для прослушиваемого сокета дескриптором является дескриптор 3. Массив целых чисел
Рис. 6.12. Структуры данных для сервера TCP с одним прослушиваемым сокетом
Единственная ненулевая запись в наборе дескрипторов — это запись для прослушиваемого сокета, и поэтому первый аргумент функции
Когда первый клиент устанавливает соединение с нашим сервером, прослушиваемый дескриптор становится доступным для чтения и сервер вызывает функцию
Рис. 6.13. Сервер TCP после того как первый клиент устанавливает соединение
Теперь наш сервер должен запомнить новый присоединенный сокет в своем массиве
Рис. 6.14. Структуры данных после того как установлено соединение с первым клиентом
Через некоторое время второй клиент устанавливает соединение, и мы получаем сценарий, показанный на рис. 6.15.
Рис. 6.15. Сервер TCP после того как установлено соединение со вторым клиентом
Новый присоединенный сокет (который имеет номер 5) должен быть размещен в памяти, в результате чего структуры данных меняются так, как показано на рис. 6.16.
Рис. 6.16. Структуры данных после того как установлено соединение со вторым клиентом
Далее мы предположим, что первый клиент завершает свое соединение. TCP-клиент отправляет сегмент FIN, превращая тем самым дескриптор номер 4 на стороне сервера в готовый для чтения. Когда наш сервер считывает этот присоединенный сокет, функция
Рис. 6.17. Структуры данных после того как первый клиент разрывает соединение
Итак, по мере того как приходят клиенты, мы записываем дескриптор их присоединенного сокета в первый свободный элемент массива
В листинге 6.3 показана первая половина этой версии сервера.
Листинг 6.3. Сервер TCP, использующий одиночный процесс и функцию select: инициализация