Книга: UNIX: разработка сетевых приложений
Упражнения
Упражнения
1. Создайте сервер TCP на основе листингов 5.1 и 5.2 и клиент TCP на основе листингов 5.3 и 5.4. Запустите сервер, затем запустите клиент. Введите несколько строк, чтобы проверить, что клиент и сервер работают. Завершите работу клиента, введя символ конца файла, и заметьте время. Используйте программу netstat
на узле клиента для проверки того, что клиентский конец соединения проходит состояние TIME_WAIT. Запускайте netstat
примерно каждые 5 с, чтобы посмотреть, когда закончится состояние TIME_WAIT. Каково время MSL для вашей реализации?
2. Что происходит с нашим соединением клиент-сервер, если мы запускаем клиент и подключаем к стандартному потоку ввода двоичный файл?
3. В чем разница между нашим соединением клиент-сервер и использованием клиента Telnet для взаимодействия с нашим эхо-сервером?
4. В нашем примере в разделе 5.12 мы проверили, что первые два сегмента завершения соединения (сегмент FIN от сервера, на который затем клиент отвечает сегментом ACK) отправляются, при просмотре состояний сокета с помощью программы netstat
. Происходит ли обмен двумя последними сегментами (FIN от клиента, на который затем сервер отвечает сегментом ACK)? Если да, то когда? Если нет, то почему?
5. Что произойдет с примером, рассмотренным в разделе 5.14, если между шагами 2 и 3 мы перезапустим сервер на узле сервера?
6. Чтобы проверить, что происходит с сигналом SIGPIPE
в разделе 5.13, измените листинг 5.3 следующим образом. Напишите обработчик сигнала для SIGPIPE
, который будет просто выводить сообщение и возвращать управление. Установите этот обработчик сигнала перед вызовом функции connect
. Измените номер порта сервера на 13 (порт сервера времени и даты). Когда соединение установится, с помощью функции sleep
войдите в состояние ожидания на 2 с, с помощью функции write
запишите несколько байтов в сокет, проведите в состоянии ожидания (sleep
) еще 2 с и с помощью функции write
запишите еще несколько байтов. Запустите программу. Что происходит?
7. Что произойдет на рис. 5.5, если IP-адрес узла сервера, заданный клиентом при вызове функции connect
, является IP-адресом, связанным с крайним правым канальным уровнем на стороне сервера, а не IP-адресом, связанным с крайним левым канальным уровнем?
8. В нашем примере эхо-сервера, осуществляющего сложение двух целых чисел (см. листинг 5.14), когда клиент и сервер принадлежат системам с различным порядком байтов, для небольших положительных чисел получается правильный ответ, но для небольших отрицательных чисел ответ неверен. Почему? (Подсказка: нарисуйте схему обмена значениями через сокет, аналогичную рис. 3.4.)
9. В нашем примере в листинге 5.13 и 5.14 можем ли мы решить проблему, связанную с различным порядком байтов на стороне клиента и на стороне сервера, если клиент преобразует два аргумента в сетевой порядок байтов, используя функцию htonl
, а сервер затем вызывает функцию ntohl
для каждого аргумента перед сложением и выполняет аналогичное преобразование результата?
10. Что произойдет в листинге 5.13 и 5.14, если в качестве узла клиента используется компьютер SPARC, где данные типа long
занимают 32 бита, а в качестве узла сервера — Digital Alpha, где данные типа long
занимают 64 бита? Изменится ли что-либо, если клиент и сервер поменяются местами?
11. На рис. 5.5 указано, что IP-адрес клиента выбирается IP на основе маршрутизации. Что это значит?
- 5.1. Введение
- 5.2. Эхо-сервер TCP: функция main
- 5.3. Эхо-сервер TCP: функция str_echo
- 5.4. Эхо-клиент TCP: функция main
- 5.5. Эхо-клиент TCP: функция str_cli
- 5.6. Нормальный запуск
- 5.7. Нормальное завершение
- 5.8. Обработка сигналов POSIX
- 5.9. Обработка сигнала SIGCHLD
- 5.10. Функции wait и waitpid
- 5.11. Прерывание соединения перед завершением функции accept
- 5.12. Завершение процесса сервера
- 5.13. Сигнал SIGPIPE
- 5.14. Сбой на узле сервера
- 5.15. Сбой и перезагрузка на узле сервера
- 5.16. Выключение узла сервера
- 5.17. Итоговый пример TCP
- 5.18. Формат данных
- 5.19. Резюме
- Упражнения