8.2. Если протокол использует структуры адреса сокета переменной длины, clilen
может быть слишком длинным. В главе 15 будет показано, что это не вызывает проблем со структурами адреса доменного сокета Unix, но корректным решением будет использовать для функции sendto
фактическую длину, возвращаемую функцией recvfrom
.
8.4. Запуск программы ping
с такими параметрами позволяет просмотреть ICMP-сообщения, получаемые узлом, на котором она запущена. Мы используем уменьшенное количество отправляемых пакетов вместо обычного значения 1 пакет в секунду, только чтобы уменьшить объем выводимой на экран информации. Если запустить наш UDP-клиент на узле solaris
, указав IP-адрес сервера 192.168.42.1, а затем запустить программу ping
, получим следующий вывод:
aix % ping -v -I 60 127.0.0.1
PING 127.0.0.1: {127.0.0.1}: 56 data bytes
64 bytes from 127 0.0.1: icmp_seq=0 ttl=255 time=0 ms
36 bytes from 192.168.42.1: Destination Port Unreachable
Vr HL TOS Len ID Fig Off TTL Pro cks Src Dst Data
4 5 00 0022 0007 0 0000 1e 11 c770 192 168 42.2 192.168.42.1
UDP: from port 40645. to port 9877 (decimal)
He все версии ping выводят сообщения об ICMP-ошибках, даже если задан параметр -v.
8.5. Прослушиваемый сокет может иметь приемный буфер определенного размера, но прослушиваемым TCP-сокетом данные никогда не принимаются. Большинство реализаций не выделяют заранее память под буферы отправки и приема. Размеры буферов сокета, определяемые параметрами SO_SNDBUF
и SO_RCVBUF
, являются предельными значениями для соответствующего сокета.
8.6. Запустим программу sock
с параметром -u
(использовать UDP) и параметром -l
(определяет локальный адрес и порт) на многоинтерфейсном узле freebsd
.
freebsd % sock -u -l 12.106.32.254.4444 192.168.42.2 8888
hello
Локальный IP-адрес подключен к Интернету (см. рис. 1.7), но чтобы достичь получателя, дейтаграмма должна выйти через другой интерфейс. Наблюдая за сетью с помощью программы tcpdump
, мы увидим, что IP-адрес отправителя, связанный с клиентом, не является адресом исходящего интерфейса.
14:28:29.614846 12.106.32.254.444 > 192.168.42.2.8888. udp 6
14:28:29.615255 192.168.42.2 > 12 106.32.254: icmp: 192.168 42.2
udp port 8888 unreachable
8.7. Использование функции printf
на стороне клиента приведет к возникновению задержки между отправками дейтаграмм, что позволит серверу получать большее количество дейтаграмм. Использование функции printf
на стороне сервера приведет к тому, что сервер будет терять большее количество дейтаграмм.
8.8. Наибольший размер IPv4-дейтаграммы составляет 65 535 байт и ограничивается 16-разрядным полем полной длины, показанным на рис. А.1. IP-заголовок требует 20 байт, UDP-заголовок — 8 байт, и для пользовательских данных остается не более 65 507 байт. В IPv6 (без поддержки джумбограмм) размер IP-заголовка составляет 40 байт, и под пользовательские данные отводится 65 487 байт.
В листинге Д.3 приведена новая версия dg_cli
. Если забыть установить размер буфера отправки, Беркли-ядра возвратят из функции sendto
ошибку EMSGSIZE
, поскольку размер буфера отправки сокета обычно меньше, чем максимально возможный размер UDP-дейтаграммы (чтобы убедиться в этом, выполните упражнение 7.1).
Листинг Д.3. Запись дейтаграммы UDP/IPv4 максимального размера
//udpcliserv/dgclibig.c
1 #include "unp.h"
2 #undef MAXLINE
3 #define MAXLINE 65507
4 void
5 dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
6 {
7 int size;
8 char sendline[MAXLINE], recvline[MAXLINE + 1];
9 ssize_t n;
10 size = 70000;
11 Setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
12 Setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
13 Sendto(sockfd, sendline, MAXLINE, 0, pservaddr, servlen);
14 n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL);
Вильям Л Саймон , Вильям Саймон , Наталья Владимировна Макеева , Нора Робертс , Юрий Викторович Щербатых
Зарубежная компьютерная, околокомпьютерная литература / ОС и Сети, интернет / Короткие любовные романы / Психология / Прочая справочная литература / Образование и наука / Книги по IT / Словари и Энциклопедии