UNIX: разработка сетевых приложений
Выделенный сокет может быть передан потоку или дочернему процессу для обработки запросов клиента. Листинг 23.15 демонстрирует новую модифицированную версию сервера, который обрабатывает первое сообщение клиента, выделяет ассоциацию при помощи
, порождает дочерний процесс и вызывает функциюsctp_peeloffдля TCP, которая была написана в разделе 5.3. Адрес из полученного сообщения мы передаем нашей функции из раздела 23.8, которая по этому адресу определяет идентификатор ассоциации. Идентификатор хранится также в полеstr_echo,sri. Наша функция служит лишь иллюстрацией использования альтернативного метода. Породив процесс, сервер переходит к обработке следующего сообщения.sinfo_assoc_idЛистинг 23.15. Параллельный сервер SCTP
//sctp/sctpserv_fork.c23 for (;;) {24 len = sizeof(struct sockaddr_in);25 rd_sz = Sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf),26 (SA*)&cliaddr, &len, &sri, &msg_flags);27 Sctp_sendmsg(sock_fd, readbuf, rd_sz,28 (SA*)&cliaddr, len,29 sri.sinfo_ppid,30 sri.sinfo_flags, sn.sinfo_stream, 0, 0);31 assoc = sctp_address_to_associd(sock_fd, (SA*)&cliaddr, len);32 if ((int)assoc == 0) {33 err_ret("Can't get association id");34 continue;35 }36 connfd = sctp_peeloff(sock_fd, assoc);37 if (connfd == -1) {38 err_ret("sctp_peeloff fails");39 continue;40 }41 if ((childpid = fork()) == 0) {42 Close(sock_fd);43 str_echo(connfd);44 exit(0);45 } else {46 Close(connfd);47 }48 }Получение и обработка первого сообщенияСервер получает и обрабатывает первое сообщение клиента.26-30Преобразование адреса в идентификатор ассоциацииСервер вызывает функцию из листинга 23.13 для получения идентификатора ассоциации по ее адресу. Если что-то мешает серверу получить идентификатор, он не делает попыток породить дочерний процесс, а просто переходит к обработке следующего сообщения.31-35Выделение ассоциацииСервер выделяет ассоциацию в отдельный дескриптор сокета при помощи36-40. Полученный сокет типа «один-к-одному» может быть без проблем передан написанной ранее для TCP функцииsctp_peeloff.str_echoПередача работы дочернему процессуСервер порождает дочерний процесс, который и выполняет всю обработку по конкретному дескриптору.41-4723.11. Управление таймерами
Протокол SCTP имеет множество численных пользовательских параметров. Все они устанавливаются через параметры сокетов, рассмотренные в разделе 7.10. Далее мы займемся рассмотрением нескольких параметров, определяющих задержку перед объявлением об отказе ассоциации или адреса собеседника.
Время обнаружения отказа в SCTP определяется семью переменными (табл. 23.1).
Таблица 23.1. Поля таймеров SCTP
Поле Описание По умолчанию Единицы srto_min Минимальный тайм-аут повторной передачи 1000 Мс srto_max Максимальный тайм-аут повторной передачи 60000 Мс srto_initial Начальный тайм-аут повторной передачи 3000 Мс sinit_max_init_timeo Максимальный тайм-аут повторной передачи сегмента INIT 3000 Мс sinit_max_attempts Максимальное количество повторных передач сегмента INIT 8 попыток spp_pathmaxrxt Максимальное количество повторных передач по адресу 5 попыток sasoc_asocmaxrxt Максимальное количество повторных передач на ассоциацию 10 попыток Эти параметры можно воспринимать как регуляторы, укорачивающие и удлиняющие время обнаружения отказа. Рассмотрим два сценария.
1. Конечная точка SCTP пытается открыть ассоциацию с собеседником, отключившимся от сети.
2. Две многоинтерфейсные конечные точки SCTP обмениваются данными. Одна из них отключается от сети питания в момент передачи данных. Сообщения ICMP фильтруются защитными экранами и потому не достигают второй конечной точки.
В сценарии 1 система, пытающаяся открыть соединение, устанавливает таймер RTO равным
(3000 мс). После первой повторной передачи пакета INIT таймер устанавливается на значение 6000 мс. Это продолжается до тех пор, пока не будет сделаноsrto_initialпопыток (9 штук), между которыми пройдут семь тайм-аутов. Удвоение таймера закончится на величинеsinit_max_attempts, равной 60 000 мс. Таким образом, через 3 + 6 + 12 + 24 + 48 + 60 + 60 + 60 = 273 с стек SCTP объявит потенциального собеседника недоступным.sinit_max_init_timeoВращением нескольких «ручек» мы можем удлинять и укорачивать это время. Начнем с двух параметров, позволяющих уменьшить общую задержку. Сократим количество повторных передач, изменив переменную
. Альтернативное изменение может состоять в уменьшении максимального тайм- аута для пакета INIT (переменнаяsinit_max_attempts). Если количество попыток снизить до 4, время детектирования резко упадет до 45 с (одна шестая первоначального значения). Однако у этого метода есть недостаток: из-за проблем в сети или перегруженности собеседника мы можем объявить его недоступным, даже если это состояние является лишь временным.srto_max_init_timeo