UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
При успешном выполнении функция
socket
sockfd
AF_xxx и PF_xxx
Префикс
AF_
PF_
PF_
AF_
<sys/socket.h>
PF_
AF_
Просмотр 137 программ с вызовами функции socket в реализации BSD/OS 2.1 показывает, что в 143 случаях вызова задается значение AF_, и только в 8 случаях — значение PF_.
Причина создания аналогичных наборов констант с префиксами AF_ и PF_ восходит к 4.1cBSD [69] и к версии функции socket, предшествующей описываемой нами версии (которая появилась с 4.2BSD). Версия функции socket в 4.1cBSD получала четыре аргумента, одним из которых был указатель на структуру sockproto. Первый элемент этой структуры назывался sp_family, и его значение было одним из значений PF_. Второй элемент, sp_protocol, был номером протокола, аналогично третьему аргументу нынешней функции socket. Единственный способ задать семейство протоколов заключался в том, чтобы задать эту структуру. Следовательно, в этой системе значения PF_ использовались как элементы для задания семейства протоколов в структуре sockproto. Значения AF_ играли роль элементов для задания семейства адресов в структурах адресов сокетов. Структура sockproto еще присутствует в 4.4BSD [128, с. 626-627], но служит только для внутреннего использования ядром. Начальное определение содержало для элемента sp_family комментарий «семейство протоколов», но в исходном коде 4.4BSD он был изменен на «семейство адресов».
Еще большую путаницу в эту ситуацию вносит то, что в Беркли-реализации структура данных ядра, содержащая значение, которое сравнивается с первым аргументом функции socket (элемент dom_family структуры domain [128, с. 187]), сопровождается комментарием, где сказано, что в этой структуре содержится значение AF_. Но некоторые структуры domain внутри ядра инициализированы с помощью константы AF_ [128, с. 192], в то время как другие — с помощью PF_ [128, с. 646], [112, с. 229].
Еще одно историческое замечание. Страница руководства по 4.2BSD от июля 1983 года, посвященная функции socket, называет ее первый аргумент af и перечисляет его возможные значения как константы AF_.
Наконец, отметим, что POSIX задает первый аргумент функции socket как значение PF_, а значение AF_ использует для структуры адреса сокета. Но далее в структуре addrinfo определяется только одно значение семейства (см. раздел 11.2), предназначенное для использования либо в вызове функции socket, либо в структуре адреса сокета!
В целях согласования с существующей практикой программирования мы используем в тексте только константы
AF_
PF_
socket
4.3. Функция connect
Функция
connect
#include <sys/socket.h>
int connect(int <i>sockfd</i>, const struct sockaddr *<i>servaddr</i>,
socklen_t <i>addrlen</i>);
<i>Возвращает: 0 в случае успешного выполнения функции, -1 в случае ошибки</i>
Аргумент
sockfd
socket
Клиенту нет необходимости вызывать функцию
bind
connect
В случае сокета TCP функция
connect
1. Если клиент TCP не получает ответа на свой сегмент SYN, возвращается сообщение
ETIMEDOUT
connect
Некоторые системы позволяют администратору устанавливать значение времени ожидания; см. приложение Е [111].
2. Если на сегмент SYN сервер отвечает сегментом RST, это означает, что ни один процесс на узле сервера не находится в ожидании подключения к указанному нами порту (например, нужный процесс может быть не запущен). Это устойчивая неисправность (hard error), и клиенту возвращается сообщение
ECONNREFUSED
RST (от «reset» — сброс) — это сегмент TCP, отправляемый собеседнику при возникновении ошибок. Вот три условия, при которых генерируется RST: сегмент SYN приходит для порта, не имеющего прослушивающего сервера (что мы только что описали); TCP хочет разорвать существующее соединение; TCP получает сегмент для несуществующего соединения (дополнительная информация содержится на с. 246–250 [111]).
3. Если сегмент SYN клиента приводит к получению сообщения ICMP о недоступности получателя от какого-либо промежуточного маршрутизатора, это считается случайным сбоем (soft error). Клиентское ядро сохраняет сообщение об ошибке, но продолжает отправлять сегменты SYN с теми же временными интервалами, что и в первом сценарии. Если же но истечении определенного фиксированного времени (75 с для 4.4BSD) ответ не получен, сохраненная ошибка ICMP возвращается процессу либо как
EHOSTUNREACH
ENETUNREACH
connect