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

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

Шрифт:

46 #endif

47 #ifdef MSG_MCAST

48 if (flags & MSG_MCAST)

49 printf(" (multicast)");

50 #endif

51 printf("\n");

52 Sendto(sockfd, mesg, n, 0, pcliaddr, len);

53 }

54 }

Изменение MAXLINE

2-3
Мы удаляем существующее определение
MAXLINE
, имеющееся в нашем заголовочном файле
unp.h
, и задаем новое значение — 20. Это позволит нам увидеть, что произойдет, когда мы получим дейтаграмму UDP, превосходящую размер буфера, переданного функции (в данном случае функции
recvmsg
).

Установка параметров сокета IP_RECVDSTADDR и IP_RECVIF

14-21
Если параметр сокета
IP_RECVDSTADDR
определен, мы включаем его. Аналогично включается параметр сокета
IP_RECVIF
.

Чтение дейтаграммы, вывод IP-адреса отправителя и порта

24-28
Дейтаграмма читается с помощью вызова функции
recvfrom_flags
. IP-адрес отправителя и порт ответа сервера преобразуются в формат представления функцией
sock_ntop
.

Вывод IP-адреса получателя

29-31
Если возвращаемый IP-адрес ненулевой, он преобразуется в формат представления функцией
inet_ntop
и выводится.

Вывод имени интерфейса, на котором была получена дейтаграмма

32-34
Если индекс интерфейса ненулевой, его имя будет возвращено функцией
if_indextoname
. Это имя наша функция печатает на экране.

Проверка различных флагов

35-51
Мы проверяем четыре дополнительных флага и выводим сообщение, если какие-либо из них установлены.

22.3. Обрезанные дейтаграммы

В системах, происходящих от BSD, при получении UDP-дейтаграммы, размер которой больше буфера приложения, функция recvmsg устанавливает флаг

MSG_TRUNC
в элементе
msg_flags
структуры
msghdr
(см. табл. 14.2). Все Беркли-реализации, поддерживающие структуру
msghdr
с элементом
msg_flags
, обеспечивают это уведомление.

ПРИМЕЧАНИЕ

Это пример флага, который должен быть возвращен процессу ядром. В разделе 14.3 мы упомянули о проблеме разработки функций recv и recvfrom: их аргумент flags является целым числом, что позволяет передавать флаги от процесса к ядру, но не наоборот.

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

1. Лишние байты игнорируются, и приложение получает флаг

MSG_TRUNC
, что требует вызова функции
recvmsg
.

2. Игнорирование лишних байтов без уведомления приложения.

3. Сохранение лишних байтов и возвращение их в последующих операциях чтения на сокете.

ПРИМЕЧАНИЕ

POSIX задает первый тип поведения: игнорирование лишних байтов и установку флага MSG_TRUNC. Ранние реализации SVR4 действуют по третьему сценарию.

Поскольку способ обработки дейтаграмм, превышающих размер приемного буфера приложения, зависит от реализации, одним из решений, позволяющий обнаружить ошибку, будет всегда использовать буфер приложения на 1 байт больше самой большой дейтаграммы, которую приложение предположительно может получить. Если все же будет получена дейтаграмма, длина которой равна размеру буфера, это явно будет свидетельствовать об ошибке.

22.4. Когда UDP оказывается предпочтительнее TCP

В разделах 2.3 и 2.4 мы описали основные различия между UDP и TCP. Поскольку мы знаем, что TCP надежен, a UDP — нет, возникает вопрос: когда следует использовать UDP вместо TCP и почему? Сначала перечислим преимущества UDP:

Как видно из табл. 20.1, UDP поддерживает широковещательную и направленную передачу. Действительно, использование UDP обязательно, если приложению требуется широковещательная или многоадресная передача. Эти два режима адресации мы рассматривали в главах 20 и 21.

UDP не требует установки и разрыва соединения. В соответствии с рис. 2.5 UDP позволяет осуществить обмен запросом и ответом в двух пакетах (если предположить, что размеры запроса и ответа меньше минимального размера MTU между двумя оконечными системами). В случае TCP требуется около 10 пакетов, если считать, что для каждого обмена «запрос-ответ» устанавливается новое соединение TCP.

Для анализа количества передаваемых пакетов важным фактором является также число циклов обращения пакетов, необходимых для получения ответа. Это становится важно, если время ожидания превышает пропускную способность, как показано в приложении А [112]. В этом тексте сказано, что минимальное время транзакциидля запроса-ответа UDP равно RTT + SPT, где RTT — это время обращения между клиентом и сервером, a SPT — время обработки запроса сервером. Однако в случае TCP, если для осуществления каждой последовательности «запрос-ответ» используется новое соединение TCP, минимальное время транзакции будет равно 2xRTT+SPT, то есть на один период RTT больше, чем для UDP.

  • Читать дальше
  • 1
  • ...
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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