Что произойдет, если вы вызовете функцию udp_client
, как было предложено, не задавая аргумент hostname
, поскольку функция udp_client
не задает значение AI_PASSIVE
функции getaddrinfo
?
6. Соедините клиент, показанный в листинге 22.4, с эхо-сервером через Интернет, изменив функции rtt_
так, чтобы выводилось каждое значение RTT. Также измените функцию dg_send_recv
, чтобы она выводила каждый полученный порядковый номер. Изобразите на графике полученные в результате значения RTT вместе с оценочными значениями RTT и среднего отклонения.
Глава 23
Дополнительные сведения о сокетах SCTP
В этой главе мы займемся углубленным рассмотрением SCTP, изучим особенности этого протокола и параметры сокетов, при помощи которых он управляется. Мы обсудим некоторые специальные вопросы, в частности, управление обнаружением отказов, доставку неупорядоченных данных, а также уведомления. Мы будем щедро иллюстрировать наши утверждения примерами программ, которые помогут читателю получить представление об использовании расширенных функций SCTP.
SCTP — протокол, ориентированный на передачу сообщений. Он способен доставлять сообщения конечному пользователю как целиком, так и по частям. Доставка по частям включается только в том случае, если приложение отправляет собеседнику большие сообщения (то есть такие, размер которых превышает половину размера буфера). Части разных сообщений никогда не смешиваются друг с другом. Приложение получает сообщение либо одним вызовом функции чтения, либо несколькими последовательными вызовами. Метод работы с механизмом частичной доставки мы продемонстрируем на примере вспомогательной функции.
Серверы SCTP могут быть как последовательными, так и параллельными в зависимости от того, какой тип интерфейса выберет разработчик приложения. SCTP предоставляет средства извлечения ассоциации из сокета типа «один-ко-многим» в отдельный сокет типа «один-к-одному». Благодаря этому появляется возможность создания последовательно-параллельных серверов.
23.2. Сервер типа «один-ко-многим» с автоматическим закрытием
Вспомните программу-сервер, которую мы написали в главе 10. Эта программа не отслеживала ассоциации. Сервер рассчитывал, что клиент самостоятельно закроет ассоциацию, удалив тем самым данные о ее состоянии. Однако такой подход делает сервер уязвимым: что если клиент откроет ассоциацию, но никаких данных не пришлет? Для такого клиента будут выделены ресурсы, которые он не использует. Неудачное стечение обстоятельств может привести к DoS-атаке на нашу реализацию SCTP со стороны неактивных клиентов. Для предотвращения подобных ситуаций в SCTP была добавлена функция автоматического закрытия ассоциаций (autoclose).
Автоматическое закрытие позволяет конечной точке SCTP задавать максимальную длительность бездействия ассоциации. Ассоциация считается бездействующей, если по ней не передаются никакие данные (ни в одном направлении). Если длительность бездействия превышает установленное ограничение, ассоциация автоматически закрывается реализацией SCTP.
Особое внимание следует уделить выбору ограничения на время бездействия. Значение не должно быть слишком маленьким, иначе сервер может в какой-то момент обнаружить, что ему требуется передать данные по уже закрытой ассоциации. На повторное открытие ассоциации будут затрачены ресурсы, да и вообще маловероятно, что клиент будет готов принять входящую ассоциацию. В листинге 23.1 [1] Все исходные коды программ, опубликованные в этой книге, вы можете найти по адресу http://www.piter.com.
приведена новая версия кода нашего сервера, в которую добавлены вызовы, защищающие этот сервер от неактивных клиентов. Как отмечалось в разделе 7.10, функция автоматического закрытия по умолчанию отключена и должна быть включена явным образом при помощи параметра сокета SCTP_AUTOCLOSE
.
Листинг 23.1. Включение автоматического закрытия сокета на сервере
//sctp/sctpserv04.c
14 if (argc == 2)
15 stream_increment = atoi(argv[1]);
16 sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
17 close_time = 120;
18 Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_AUTOCLOSE,
19 &close_time, sizeof(close_time));
20 bzero(&servaddr, sizeof(servaddr));
21 servaddr.sin_family = AF_INET;
22 servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
23 servaddr.sin_report = htons(SERV_PORT);
Установка автоматического закрытия
17-19
Сервер устанавливает ограничение на простой ассоциаций равным 120 с и помещает это значение в переменную close_time
. Затем сервер вызывает функцию setsockopt
с параметром SCTP_AUTOCLOSE
, устанавливающим выбранное ограничение. В остальном код сервера остается прежним.
Читать дальше
Конец ознакомительного отрывка
Купить книгу