Вход/Регистрация
UNIX: разработка сетевых приложений
вернуться

Стивенс Уильям Ричард

Шрифт:

struct ip6_mtuinfo {

struct sockaddr_in6 ip6m_addr; /* адрес узла */

uint32_t ip6m_mtu; /* транспортная MTU

в порядке байтов узла */

};

Эта структура определяется включением заголовочного файла

<netinet/in.h>
.

Определение текущей транспортной MTU

Если приложение не отслеживало изменения MTU при помощи параметра

IPV6_RECVPATHMTU
, оно может определить текущее значение транспортной MTU присоединенногосокета при помощи параметра
IPV6_PATHMTU
. Этот параметр доступен только для чтения и возвращает он структуру
ip6_mtuinfo
(см. выше), в которой хранится текущее значение MTU. Если значение еще не было определено, возвращается значение MTU по умолчанию для исходящего интерфейса. Значение адреса из структуры
ip6_mtuinfo
в данном случае не определено.

Отключение фрагментации

По умолчанию стек IPv6 фрагментирует исходящие пакеты по транспортной MTU. Приложениям типа

traceroute
автоматическая фрагментация не нужна, потому что им нужно иметь возможность самостоятельно определять транспортную MTU. Параметр сокета
IPV6_DONTFRAG
используется для отключения автоматической фрагментации: значение 0 (по умолчанию) разрешает фрагментацию, тогда как значение 1 отключает ее.

Когда автоматическая фрагментация отключена, вызов send со слишком большим пакетом может возвратить ошибку

EMSGSIZE
, но это не является обязательным. Единственным способом определить необходимость фрагментации пакета является использование параметра сокета
IPV6_RECVPATHMTU
, который мы описали выше.

Параметр

IPV6_DONTFRAG
может передаваться и во вспомогательных данных. При этом элемент
cmsg_level
структуры
cmsghdr
должен иметь значение
IPPROTO_IPV6
, а элемент
cmsg_type
должен иметь значение
IPV6_DONTFRAG
. Первый байт данных должен быть первым байтом четырехбайтового целого.

22.10. Резюме

Существуют приложения, которым требуется знать IP-адрес получателя дейтаграммы UDP и интерфейс, на котором была получена эта дейтаграмма. Чтобы получать эту информацию в виде вспомогательных данных для каждой дейтаграммы, можно установить параметры сокета

IP_RECVDSTADDR
и
IP_RFCVIF
. Аналогичная информация вместе с предельным значением количества транзитных узлов полученной дейтаграммы для сокетов IPv6 становится доступна при включении параметра сокета
IPV6_PKTINFO
.

Несмотря на множество полезных свойств, предоставляемых протоколом TCP и отсутствующих в UDP, существуют ситуации, когда следует отдать предпочтение UDP. UDP должениспользоваться для широковещательной или многоадресной передачи. UDP можетиспользоваться в простых сценариях «запрос-ответ», но тогда приложение должно само обеспечить некоторую функциональность, повышающую надежность протокола UDP. UDP не следуетиспользовать для передачи большого количества данных.

В разделе 22.5 мы добавили нашему клиенту UDP определенные функциональные возможности, повышающие его надежность за счет обнаружения факта потери пакетов, для чего используются тайм-аут и повторная передача. Мы изменяли тайм-аут повторной передачи динамически, снабжая каждый пакет отметкой времени и отслеживая два параметра: период обращения RTT и его среднее отклонение. Мы также добавили порядковые номера, чтобы проверять, что данный ответ — это ожидаемый нами ответ на определенный запрос. Наш клиент продолжал использовать простой протокол остановки и ожидания (stop-and-wait), а приложения такого типа допускают применение UDP.

Упражнения

1. Почему в листинге 22.16 функция

printf
вызывается дважды?

2. Может ли когда-нибудь функция

dg_send_recv
(см. листинги 22.6 и 22.7) возвратить нуль?

3. Перепишите функцию

dg_send_recv
с использованием функции
select
и ее таймера вместо
alarm
,
SIGALRM
,
sigsetjmp
и
siglongjmp
.

4. Как может сервер IPv4 гарантировать, что адрес отправителя в его ответе совпадает с адресом получателя клиентского запроса? (Аналогичную функциональность предоставляет параметр сокета

IPV6_PKTINFO
.)

5. Функция

main
в разделе 22.6 является зависящей от протокола (IPv4). Перепишите ее, чтобы она стала не зависящей от протокола. Потребуйте, чтобы пользователь задал один или два аргумента командной строки, первый из которых — необязательный IP-адрес (например, 0.0.0.0 или 0::0), а второй — обязательный номер порта. Затем вызовите функцию
udp_client
, чтобы получить семейство адресов, номер порта и длину структуры адреса сокета.

Что произойдет, если вы вызовете функцию

udp_client
, как было предложено, не задавая аргумент
hostname
, поскольку функция
udp_client
не задает значение
AI_PASSIVE
функции
getaddrinfo
?

  • Читать дальше
  • 1
  • ...
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: