Литмир - Электронная Библиотека
Содержание  
A
A

Параметр сокета

SO_KEEPALIVE
устанавливается многими серверами TCP и автоматически закрывает наполовину открытое соединение. Замечательное свойство этого параметра в том, что он обрабатывается на уровне TCP, не требуя на уровне приложения наличия таймера, измеряющего период отсутствия активности. Однако недостаток этого параметра в том, что он не видит разницы между выходом собеседника из строя и временной потерей соединения с ним. SCTP предоставляет 17 параметров сокетов, с помощью которых приложение может управлять транспортным уровнем.
SCTP_NODELAY
и
SCTP_MAXSEG
аналогичны
TCP_NODELAY
и
TCP_MAXSEG
, и выполняют схожие функции. Остальные 17 параметров позволяют приложению более точно контролировать поведение стека SCTP. Большинство этих параметров будет рассмотрено в главе 23.

Параметр сокета

SO_LINGER
расширяет наши возможности в отношении контроля над функцией
close
 — мы можем отложить ее завершение на некоторое время. Кроме того, этот параметр позволяет нам отправить сегмент RST вместо обычной последовательности из четырех пакетов, завершающих соединение TCP. Следует соблюдать осторожность при отправке сегментов RST, поскольку в этом случае не наступает состояние TCP TIME_WAIT. Бывает, что этот параметр сокета не обеспечивает необходимой нам информации, и тогда требуется реализовать подтверждение на уровне приложения.

У каждого сокета TCP имеется буфер отправки и буфер приема, а у каждого сокета UDP есть буфер приема. Параметры сокета

SO_SNDBUF
и
SO_RCVBUF
позволяют нам изменять размеры этих буферов. Основное применение эти функции находят при передаче большого количества данных по каналам с повышенной пропускной способностью, которые представляют собой соединения TCP либо с широкой полосой пропускания, либо с большой задержкой, часто с использованием расширений из RFC 1323. Сокеты UDP, наоборот, могут стремиться увеличить размер приемного буфера, чтобы позволить ядру установить в очередь больше дейтаграмм, если приложение занято.

Упражнения

1. Напишите программу, которая выводит заданные по умолчанию размеры буферов отправки и приема TCP, UDP и SCTP, и запустите ее в системе, к которой у вас имеется доступ.

2. Измените листинг 1.1 следующим образом. Перед вызовом функции connect вызовите функцию

getsockopt
, чтобы получить размер приемного буфера сокета и MSS. Выведите оба значения. После успешного завершения функции извлеките значения тех же двух параметров сокета и выведите их. Изменились ли значения? Почему? Запустите программу, соединяющуюся с сервером в вашей локальной сети, и программу, соединяющуюся с сервером в удаленной сети. Изменяется ли MSS? Почему? Запустите также программу на разных узлах, к которым у вас есть доступ.

3. Запустите наш сервер TCP, приведенный в листингах 5.1 и 5.2, и наш клиент из листингов 5.3 и 5.4. Измените функцию

main
клиента, чтобы установить параметр сокета
SO_LINGER
перед вызовом функции
exit
, задав
l_onoff
равным 1, а
l_linger
 — равным 0. Запустите сервер, а затем запустите клиент. Введите строку или две на стороне клиента для проверки работоспособности, а затем завершите работу клиента, введя символ конца файла. Что происходит? После завершения работы клиента запустите программу
netstat
на узле клиента и посмотрите, проходит ли сокет через состояние TIME_WAIT.

4. Будем считать, что два клиента TCP запускаются одновременно. Оба устанавливают параметр сокета

SO_REUSEADDR
и затем с помощью функции
bind
связываются с одним и тем же локальным IP-адресом и одним и тем же локальным портом (допустим, 1500). Но один из клиентов соединяется с помощью функции connect с адресом 198.69.10.2, порт 7000, а второй — с адресом 198.69.10.2 (тот же IP-адрес собеседника), порт 8000. Опишите возникающую ситуацию гонок.

5. Получите исходный код для примеров в этой книге (см. предисловие) и откомпилируйте программу sock (см. раздел В.3). Сначала классифицируйте свой узел как узел, не поддерживающий многоадресную передачу, затем — как поддерживающий многоадресную передачу, но не поддерживающий параметр

SO_REUSEPORT
, и наконец, как узел, поддерживающий многоадресную передачу с предоставлением параметра
SO_REUSEPORT
. Попытайтесь запустить несколько экземпляров программы sock в качестве сервера TCP (параметр
-s
командной строки) на одном и том же порте, связывая универсальный адрес, один из адресов интерфейсов вашего узла и адрес закольцовки (loopback address). Нужно ли вам задавать параметр
SO_REUSEADDR
(параметр
командной строки)? Используйте программу
netstat
для просмотра прослушиваемых сокетов.

6. Продолжайте предыдущий пример, но запустите сервер UDP (параметр

-u
командной строки) и попытайтесь запустить два экземпляра, связанные с одними и теми же локальным IP-адресом и портом. Если ваша реализация поддерживает параметр
SO_REUSEPORT
, попытайтесь использовать ее (параметр
-T
командной строки).

7. Многие версии утилиты

ping
имеют флаг
-d
, задающий параметр сокета
SO_DEBUG
. В чем его назначение?

8. Продолжая пример в конце нашего обсуждения параметра сокета

TCP_NODELAY
, предположим, что клиент выполняет две операции записи с помощью функции
write
: первую для 4 байт данных и вторую для 396 байт. Также будем считать, что время задержки ACK — 100 мс, период RTT между клиентом и сервером равен 100 мс, а время обработки сервером каждого клиентского запроса — 50 мс. Нарисуйте временную диаграмму, показывающую взаимодействие алгоритма Нагла с задержанными сегментами ACK.

9. Снова выполните предыдущее упражнение, считая, что установлен параметр сокета

TCP_NODELAY
.

10. Снова выполните упражнение 8, считая, что процесс вызывает функцию

writev
один раз для обоих буферов (4-байтового и 396-байтового).

11. Прочтите RFC 1122 [10], чтобы определить рекомендуемый интервал для задержанных сегментов ACK.

12. В какой из версий наш сервер тратит больше времени — в листинге 5.1 или 5.2? Что происходит, если сервер устанавливает параметр сокета

SO_KEEPALIVE
, через соединение не происходит обмена данными, узел клиента выходит из строя и не перезагружается?

13. В какой из версий наш клиент тратит больше времени — в листинге 5.3 или 5.4? Что происходит, если клиент устанавливает параметр сокета

SO_KEEPALIVE
, через соединение не происходит обмена данными и узел сервера выходит из строя и не перезагружается?

14. В какой из версий наш клиент тратит больше времени — в листинге 5.3 или 6.2? Что происходит, если клиент устанавливает параметр сокета

SO_KEEPALIVE
, через соединение не происходит обмена данными и узел сервера выходит из строя и не перезагружается?

95
{"b":"225366","o":1}