Страница 42 из 399
137 void
138 Listen(int fd, int backlog)
139 {
140 char *ptr;
141 /* может заменить второй аргумент на переменную окружения */
142 if ((ptr = getenv("LISTENQ")) != NULL)
143 backlog = atoi(ptr);
144 if (listen(fd, backlog) < 0)
145 err_sys("listen error");
146 }
■ Традиционно в руководствах и книгах утверждалось, что помещение фиксированного числа соединений в очередь позволяет обрабатывать случай загруженного серверного процесса между последовательными вызовами функции accept. При этом подразумевается, что из двух очередей больше записей будет содержаться, вероятнее всего, в очереди полностью установленных соединений. Но оказалось, что для действительно загруженных веб-серверов это не так. Причина задания большего значения backlog в том, что очередь не полностью установленных соединений растет по мере поступления сегментов SYN от клиентов; элементы очереди находятся в состоянии ожидания завершения трехэтапного рукопожатия.
■ Если очереди заполнены, когда приходит клиентский сегмент SYN, то TCP игнорирует приходящий сегмент SYN [128, с. 930–931] и не посылает RST. Это происходит потому, что состояние считается временным, и TCP клиента должен еще раз передать свой сегмент SYN, для которого в ближайшее время, вероятно, найдется место в очереди. Если бы TCP сервера послал RST, функция co
Некоторые реализации отправляют сегмент RST в описанной выше ситуации, что некорректно по изложенным выше причинам. Если вы не пишете клиент специально для работы с подобным сервером, лучше всего игнорировать такую возможность. Ее учет при кодировании клиента снизит его устойчивость и увеличит нагрузку на сеть, если окажется, что порт действительно не прослушивается сервером.
■ Данные, которые приходят после завершения трехэтапного рукопожатия, но до того, как сервер вызывает функцию accept, должны помещаться в очередь TCP-сервера, пока не будет заполнен приемный буфер.
В табл. 4.6 показано действительное число установленных в очередь соединений для различных значений аргумента backlog в операционных системах, показанных на рис. 1.7. Семь операционных систем помещены в пять колонок, что иллюстрирует многообразие значений аргумента backlog.
Таблица 4.6. Действительное количество соединений в очереди для различных значений аргумента backlog