Уильям Стивенс - UNIX: разработка сетевых приложений
- Название:UNIX: разработка сетевых приложений
- Автор:
- Жанр:
- Издательство:Питер
- Год:2007
- Город:Санкт-Петербург
- ISBN:5-94723-991-4
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Уильям Стивенс - UNIX: разработка сетевых приложений краткое содержание
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
UNIX: разработка сетевых приложений - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
42 err_quit("unable to connect");
43 while ((n = Read(sockfd, recvline, MAXLINE)) > 0) {
44 recvline[n] = 0; /* null terminate */
45 Fputs(recvline, stdout);
46 }
47 exit(0);
48 }
13-28
Первый аргумент командной строки — это имя узла, передаваемое в качестве аргумента функции gethostbyname
, а второй — имя службы, передаваемое в качестве аргумента функции getservbyname
. Наш код подразумевает использование протокола TCP, что мы указываем во втором аргументе функции getservbyname
. Если функции gethostbyname
не удается найти нужное имя, мы вызываем функцию inet_aton
(см. раздел 3.6), чтобы проверить, не является ли аргумент командной строки IP-адресом в формате ASCII. В этом случае формируется список из одного элемента — этого IP-адреса.
29-35
Теперь мы пишем вызовы функций socket
и connect
в цикле, который выполняется для каждого адреса сервера, пока попытка вызова функции connect
не окажется успешной или пока не закончится список серверов. После вызова функции socket
мы заполняем структуру адреса сокета Интернета IP-адресом и номером порта сервера. Хотя в целях увеличения производительности мы могли бы вынести из цикла вызов функции bzero
и последующие два присваивания, наш код легче читать в таком виде, как он представлен сейчас. Установление соединения с сервером редко является основным источником проблем с производительностью сетевого клиента.
36-39
Вызывается функция connect
, и если вызов оказывается успешным, функция break
завершает цикл. Если установить соединение не удается, мы выводим сообщение об ошибке и закрываем сокет. Вспомните, что дескриптор, для которого вызов функции connect
оказался неудачным, не может больше использоваться и должен быть закрыт.
41-42
Если цикл завершается, потому что ни один вызов функции connect
не закончился успехом, программа завершает работу.
43-47
Мы считываем ответ сервера и завершаем программу, когда сервер закрывает соединение.
Если мы запустим эту программу, указав один из наших узлов, на котором работает сервер времени и даты, мы получим ожидаемый результат:
freebsd % daytimetcpcli1 aix daytime
trying 192.168.42.2:13
Sun Jul 27 22:44:19 2003
Но еще интереснее запустить программу, обратившись к маршрутизатору с несколькими сетевыми интерфейсами, на котором не работает сервер времени и даты:
solaris % daytimetcpcli1 gateway.tuc.noao.edu daytime
trying 140.252.108.1:13
connect error: Operation timed out
trying 140.252.1.4:13
connect error: Operation timed out
trying 140.252.104.1:13
connect error: Connection refused
unable to connect
11.6. Функция getaddrinfo
Функции gethostbyname
и gethostbyaddr
поддерживают только IPv4. Интерфейс IPv6 разрабатывался в несколько этапов (история разработки описана в разделе 11.20), и в конечном итоге получилась функция getaddrinfo
. Последняя осуществляет трансляцию имен в адреса и служб в порты, причем возвращает она список структур sockaddr
, а не список адресов. Такие структуры могут непосредственно использоваться функциями сокетов. Благодаря этому функция getaddrinfo
скрывает все различия между протоколами в библиотеке функций. Приложение работает только со структурами адресов сокетов, которые заполняются getaddrinfo
. Эта функция определяется стандартом POSIX.
Определение этой функции в POSIX происходит от более раннего предложения Кейта Склоуэра (Keith Sklower) для функции, называемой getconninfo. Эта функция стала результатом обсуждений с Эриком Олменом (Eric Allman), Вилльямом Дастом (William Durst), Майклом Карелсом (Michael Karels) и Стивеном Вайсом (Steven Wise), а также более ранней реализации, написанной Эриком Олменом. Замечание о том, что указания имени узла и имени службы достаточно для соединения с этой службой независимо от деталей протокола, было сделано Маршалом Роузом (Marshall Rose) в проекте X/Open.
#include
int getaddrinfo(const char * hostname , const char * service ,
const struct addrinfo * hints , struct addrinfo ** result );
Возвращает: 0 в случае успешного выполнения, ненулевое значение в случае ошибки
(см. табл. 11.2).
Через указатель result
функция возвращает указатель на связный список структур addrinfo
, который задается в заголовочном файле :
struct addrinfo {
int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
int ai_family; /* AF_xxx */
int ai_socktype; /* SOCK_xxx */
int ai_protocol; /* 0 или IPPROTO_xxx для IPv4 и IPv6 */
size_t ai_addrlen; /* длина ai_addr */
char* ai_canonname; /* указатель на каноническое имя узла */
struct sockaddr *ai_addr; /* указатель на структуру адреса сокета */
struct addrinfo *ai_next; /* указатель на следующую структуру в связном
списке */
};
Переменная hostname
— это либо имя узла, либо строка адреса (точечно-десятичная запись для IPv4 или шестнадцатеричная строка для IPv6). Переменная service
— это либо имя службы, либо строка, содержащая десятичный номер порта. (См. также упражнение 11.4.)
Аргумент hints
— это либо пустой указатель, либо указатель на структуру addrinfo
, заполненную рекомендациями вызывающего процесса о типах информации, которую он хочет получить. Например, если заданная служба предоставляется и для TCP, и для UDP (служба domain
, которая ссылается на сервер DNS), вызывающий процесс может присвоить элементу ai_socktype
структуры hints
значение SOCK_DGRAM
. Тогда возвращение информации будет иметь место только для дейтаграммных сокетов.
Вызывающим процессом могут быть установлены значения следующих элементов структуры hints
:
■ ai_flags
(несколько констант AI_XXX
, объединенных операцией ИЛИ);
■ ai_family
(значение AF_xxx
);
■ ai_socktype
(значение SOCK_xxx
);
■ ai_protocol
.
Поле ai_flags
может содержать следующие константы:
■ AI_PASSIVE
указывает, что сокет будет использоваться для пассивного открытия;
■ AI_CANONNAME
указывает функции на необходимость возвратить каноническое имя узла;
■ AI_NUMERICHOST
запрещает преобразование между именами и адресами. Аргумент hostname
должен представлять собой строку адреса;
■ AI_NUMERICSERV
запрещает преобразование между именами служб и номерами портов. Аргумент service
должен представлять собой строку с десятичным номером порта;
■ AI_V4MAPPED
вместе с ai_family = AF_INET6
указывает функции на необходимость вернуть адреса IPv4 из записей А, преобразованные к IPv6, если записи типа AAAA отсутствуют;
■ AI_ALL
при указании вместе с AI_V4MAPPED
говорит о необходимости вернуть адреса IPv4, преобразованные к IPv6, вместе с истинными адресами IPv6;
Интервал:
Закладка: