Книга: UNIX: разработка сетевых приложений
Упражнения
Упражнения
1. Измените программу, представленную в листинге 11.1, так, чтобы для каждого возвращаемого адреса вызывалась функция gethostbyaddr
, а затем выведите возвращаемое имя h_name
. Сначала запустите программу, задав имя узла только с одним IP-адресом, а затем — с несколькими IP-адресами. Что происходит?
2. Устраните проблему, показанную в предыдущем упражнении.
3. Запустите программу, показанную в листинге 11.4, задав имя службы chargen
.
4. Запустите программу, показанную в листинге 11.4, задав IP-адрес в точечно- десятичной записи в качестве имени узла. Допускает ли это ваш распознаватель? Измените листинг 11.4, чтобы разрешить IP-адрес в виде строки десятичных чисел с точками в качестве имени узла и строку с десятичным номером порта в качестве имени службы. В каком порядке должно выполняться тестирование IP-адреса для строки в точечно-десятичной записи и для имени?
5. Измените программу в листинге 11.4 так, чтобы можно было работать либо с IPv4, либо с IPv6.
6. Измените программу в листинге 8.5 так, чтобы сделать запрос DNS, и сравните возвращаемый IP-адрес со всеми IP-адресами узла получателя, то есть вызовите функцию gethostbyaddr
, используя IP-адрес, возвращаемый функцией recvfrom
, а затем вызовите gethostbyname
для поиска всех IP-адресов для узла.
7. Измените листинг 11.6, чтобы вызвать функцию getnameinfo
вместо функции sock_ntop
. Какие флаги вы должны передать функции getnameinfo
?
8. В разделе 7.5 мы обсуждали завладение портом с помощью параметра сокета SO_REUSEADDR
. Чтобы увидеть, как это происходит, создайте не зависящий от протокола сервер времени и даты UDP, показанный в листинге 11.13. Запустите один экземпляр сервера в одном окне, свяжите его с универсальным адресом и некоторым портом, который вы выберете. Запустите в другом окне клиент и убедитесь, что этот сервер выполняет обработку клиента (отметьте вызов функции printf
на узле сервера). Затем запустите другой экземпляр сервера в другом окне, и на этот раз свяжите его с одним из адресов направленной передачи узла и тем же портом, что и первый сервер. С какой проблемой вы сразу же столкнетесь? Устраните эту проблему и перезапустите второй сервер. Запустите клиент, отправьте дейтаграмму и проверьте, что второй сервер захватил порт первого сервера. Если возможно, запустите второй сервер снова с учетной записью, отличной от учетной записи первого сервера, чтобы проверить, происходит ли по-прежнему захват порта, поскольку некоторые производители не допускают второго связывания, если идентификатор пользователя отличен от идентификатора процесса, уже связанного с портом.
9. В конце раздела 2.12 мы показали два примера Telnet: сервер времени и даты и эхо-сервер. Зная, что клиент проходит через два этапа — функцию gethostbyname
и функцию connect, определите, к каким этапам относятся строки вывода клиента.
10. Функции getnameinfo
может потребоваться длительное время (до 80 с) на возвращение ошибки, если для IP-адреса не может быть найдено имя узла. Напишите новую функцию getnameinfo_timeo
, которая получает дополнительный целочисленный аргумент, задающий максимальную длительность ожидания ответа в секундах. Если время таймера истекает и флаг NI_NAMEREQD
не задан, вызовите функцию inet_ntop
и возвратите строку адреса.
- 11.1. Введение
- 11.2. Система доменных имен
- 11.3. Функция gethostbyname
- 11.4 Функция gethostbyaddr
- 11.5. Функции getservbyname и getservbyport
- 11.6. Функция getaddrinfo
- 11.7. Функция gai_strerror
- 11.8. Функция freeaddrinfo
- 11.9. Функция getaddrinfo: IPv6
- 11.10. Функция getaddrinfo: примеры
- 11.11. Функция host_serv
- 11.12. Функция tcp_connect
- 11.13. Функция tcp_listen
- 11.14. Функция udp_client
- 11.15. Функция udp_connect
- 11.16. Функция udp_server
- 11.17. Функция getnameinfo
- 11.18. Функции, допускающие повторное вхождение
- 11.19. Функции gethostbyname_r и gethostbyaddr_r
- 11.20. Устаревшие функции поиска адресов IPv6
- 11.21. Другая информация о сетях
- 11.22. Резюме
- Упражнения