15 printf("received %d bytes\n", n);
16 }
Но если установить размеры буферов сокета клиента, как показано в листинге Д.3, и запустить программу, сервер ничего не возвратит. С помощью программы tcpdump
printf
, вызов функции recvfrom
не возвратит дейтаграмму. Проблема заключается в том, что приемный буфер UDP-сокета сервера меньше, чем посланная нами дейтаграмма, поэтому дейтаграмма отбрасывается и не доставляется на сокет. В системах BSD/OS это можно проверить, запустив программу netstat -s
и проверив счетчик, указывающий количество дейтаграмм, отброшенных из-за переполнения буферов сокета (dropped due to full socket buffers
), до и после получения нашей длинной дейтаграммы. Решением является модификация сервера путем задания размеров буферов приема и отправки сокета.В большинстве сетей дейтаграмма длиной 65 535 байт фрагментируется. Как отмечалось в разделе 2.9, IP-уровнем должен поддерживаться размер буфера для сборки фрагментов, равный всего лишь 576 байт. Поэтому некоторые узлы не получат дейтаграмму максимального размера, посылаемую в данном упражнении. Кроме того, во многих Беркли-реализациях, включая 4.4BSD-Lite2, имеется ошибка, связанная со знаковыми типами данных, которая не позволяет UDP принимать дейтаграммы больше, чем 32 767 байт (см. строка 95, с. 770 [128]).
Глава 9
9.1. В некоторых ситуациях функция sctp_peeloff
9.2. На стороне сервера выполняется автоматическое закрытие после закрытия ассоциации клиентом. SCTP не поддерживает состояние неполного закрытия, поэтому когда клиент вызывает close
9.3. Сокет типа «один-к-одному» требует вызова connect
9.4. Собеседник, с которым устанавливается ассоциация, может прислать данные только в том случае, если у него будет готов сегмент DATA до того, как соединение будет установлено, то есть если на обеих сторонах используются сокеты типа «один-ко-многим» и каждая сторона выполняет операцию send с неявной установкой соединения. Такой процесс установки ассоциации называется коллизией пакетов INIT и подробно описывается в главе 4 [117].
9.5. В некоторых случаях не все связанные адреса могут быть переданы собеседнику. В частности, если приложение связало с сокетом как частные, так и общие IP-адреса, собеседник получит информацию только об общих IP-адресах. Еще одним примером являются локальные в рамках канала адреса IPv6, которые не обязательно сообщаются собеседнику.
Глава 10
10.1 Если функция sctp_sendmsg
sctp_recvmsg
и заблокируется в ней навсегда, ожидая ответного сообщения, которое никогда не придет.Чтобы избежать этой неприятности, нужно проверять коды возврата. Если при отправке возникла ошибка, клиент не должен пытаться получить ответ. Ему следует просто сообщить о возникшей ошибке.
Если функция sctp_recvmsg
sctp_recvmsg
.10.2. Если сервер получает запрос и завершает работу, клиент (в его нынешней форме) зависает навечно в ожидании ответа сервера. Клиенту следует включить доставку уведомлений о событиях для данной ассоциации. Когда сервер завершит работу, клиент получит соответствующее сообщение и сможет принять какие-либо меры, например связаться с другим сервером. Альтернативным решением может быть установка таймера и завершение работы по истечении времени ожидания.