13.4. IP-адрес и номер порта клиента могут быть получены из структуры адреса сокета, заполняемой функцией accept
.
Причина, по которой демон inetd
не делает этого для UDP-сокета, состоит в том, что чтение дейтаграмм (recvfrom
) осуществляется с помощью функции exec
сервером, а не самим демоном inetd
.
Демон inetd
может считать дейтаграмму с флагом MSG_PEEK
(см. раздел 14.7), только чтобы получить IP-адрес и номер порта клиента, но оставляет саму дейтаграмму для чтения серверу.
Глава 14
14.1. Если не установлен обработчик, первый вызов функции signal
будет возвращать значение SIG_DFL
, а вызов функции signal
для восстановления обработчика просто вернет его в исходное состояние.
14.3. Приведем цикл for
:
for (;;) {
if ((n = Recv(sockfd, recvline, MAXLINE, MSG_PEEK)) == 0)
break; /* сервер закрыл соединение */
Ioctl(sockfd, FIONREAD, &npend);
printf("%d bytes from PEEK, %d bytes pending\n", n, npend);
n = Read(sockfd, recvline, MAXLINE);
recvline[n] = 0; /* завершающий нуль */
Fputs(recvline, stdout);
}
14.4. Данные продолжают выводиться, поскольку выход из функции main
— это то же самое, что и возврат из этой функции. Функция main
вызывается программой запуска на языке С следующим образом:
exit(main(argc, argv));
Следовательно, вызывается функция exit
, а затем и программа очистки стандартного ввода-вывода.
Глава 15
15.1. Функция unlink
удаляет имя файла из файловой системы, и когда клиент позже вызовет функцию connect
, она не выполнится. Это не влияет на прослушиваемый сокет сервера, но клиенты не смогут выполнить функции connect
после вызова функции unlink
.
15.2. Клиент не сможет соединиться с сервером с помощью функции connect
, даже если полное имя существует, поскольку для успешного соединения с помощью функции connect
доменный сокет Unix должен быть открыт и связан с этим полным именем (см. раздел 15.4).
15.3. При выводе адреса протокола клиента путем вызова функции sock_ntop
мы получим сообщение datagram from (no pathname bound)
(дейтаграмма от (имя не задано)), поскольку по умолчанию с сокетом клиента не связывается никакое имя.
Одним из решений является проверить доменный сокет Unix в функциях udp_client
и udp_connect
и связать с сокетом при помощи функции bind
временное полное имя. Это приведет к зависимости от протокола в библиотечной функции, но не в нашем приложении.
15.4. Даже если мы заставим сервер вернуть в функции write
1 байт на его 26- байтовый ответ, использование функции sleep
на стороне клиента гарантирует, что все 26 сегментов будут получены до вызова функции read
, в результате чего функция read
вернет полный ответ. Это еще одно подтверждение того, что TCP является потоком байтов с отсутствием границ записей.
Чтобы использовать доменные протоколы Unix, запускаем клиент и сервер с двумя аргументами командной строки /lосаl
(или /unix
) и /tmp/daytime
(или любое другое временное имя, которое вы хотите использовать). Ничего не изменится: 26 байт будут возвращаться функцией read
каждый раз, когда будет запускаться клиент.
Поскольку для каждой функции send
сервер определяет флаг MSG_EOR
, каждый байт рассматривается как логическая запись, и функция read
при каждом вызове возвращает 1 байт. Причина в том, что Беркли-реализации поддерживают флаг MSG_EOR
по умолчанию. Однако этот факт не документирован и не может использоваться в серийном коде. В данном примере мы используем эту особенность, чтобы показать разницу между потоком байтов и ориентированным на записи протоколом. С точки зрения реализации, каждая операция вывода идет в mbuf
(буфер памяти) и флаг MSG_EOR
сохраняется ядром вместе с mbuf
, когда mbuf
переходит из отправляющего сокета в приемный буфер принимающего сокета. Когда вызывается функция read, флаг MSG_EOR
все еще присоединен к каждому mbuf
, так что основная подпрограмма ядра read
(поддерживающая флаг MSG_EOR
, поскольку некоторые протоколы используют этот флаг) сама возвращает каждый байт. Если бы вместо read
мы использовали recvmsg
, флаг MSG_EOR
возвращался бы в поле msg_flags
каждый раз, когда recvmsg
возвращала бы 1 байт. Такой подход в TCP не срабатывает, поскольку отправляющий TCP не анализирует флаг MSG_EOR
в отсылаемом mbuf
и в любом случае у нас нет возможности передать этот флаг принимающему TCP в TCP-заголовке. (Выражаем благодарность Мату Томасу (Matt Thomas) за то, что он указал нам это недокументированное «средство».)
15.5. В листинге Д.7 приведена реализация данной программы.
Вильям Л Саймон , Вильям Саймон , Наталья Владимировна Макеева , Нора Робертс , Юрий Викторович Щербатых
Зарубежная компьютерная, околокомпьютерная литература / ОС и Сети, интернет / Короткие любовные романы / Психология / Прочая справочная литература / Образование и наука / Книги по IT / Словари и Энциклопедии