Книга: UNIX: разработка сетевых приложений
Упражнения
Упражнения
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
, через соединение не происходит обмена данными и узел сервера выходит из строя и не перезагружается?
15. Будем считать, что и клиент, и сервер устанавливают параметр сокета SO_KEEPALIVE
. Между собеседниками поддерживается соединение, но через это соединение не происходит обмена данными между приложениями. Когда проходят условленные 2 ч и требуется проверить наличие связи, сколькими сегментами TCP обмениваются собеседники?
16. Почти все реализации определяют константу SO_ACCEPTCONN
в заголовочном файле <sys/socket.h>
, но мы не описывали этот параметр. Прочтите [69], чтобы понять, зачем этот параметр существует.
- 7.1. Введение
- 7.2. Функции getsockopt и setsockopt
- 7.3. Проверка наличия параметра и получение значения по умолчанию
- 7.4. Состояния сокетов
- 7.5. Общие параметры сокетов
- 7.6. Параметры сокетов IPv4
- 7.7. Параметр сокета ICMPv6
- 7.8. Параметры сокетов IPv6
- 7.9. Параметры сокетов TCP
- 7.10. Параметры сокетов SCTP
- 7.11. Функция fcntl
- 7.12. Резюме
- Упражнения