Вызов функции connect
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
может содержать следующие константы:
Читать дальше
Конец ознакомительного отрывка
Купить книгу