Вход/Регистрация
Разработка приложений в среде Linux. Второе издание
вернуться

Троан Эрик В.

Шрифт:

#include <sys/types.h>

#include <socket.h>

#include <netdb.h>

void freeaddrinfo(struct addrinfo * res);

Единственным параметром для

freeaddrinfo
является указатель на первый узел в списке.

Каждый узел в возвращаемом списке имеет тип

struct addrinfo
и специфицирует один адрес, соответствующий запросу. Каждый адрес содержит не только IPv4- или IPv6-адрес, он также определяет тип соединения (например, дейтаграмма) и протокол (такой как UDP). Если для одного IP-адреса в запросе подходит несколько типов соединений, то данный адрес включается в несколько узлов.

Каждый узел содержит описанную ниже информацию.

• 

ai_family
— семейство протоколов (
PF_INET
или
PF_INET6
), к которому принадлежит адрес.

• 

ai_socktype
— тип соединения для адреса (как правило, принимает одно из значений
SOCK_STREAM
,
SOCK_DGRAM
или
SOCK_RAW
).

• 

ai_protocol
— протокол для адреса (обычно
IPPROTO_TCP
или
IPPROTO_UDP
).

• Если в параметре

hints
был указан флаг
AI_CANONNAME
, то
ai_canonname
содержит каноническое имя для адреса.

• 

ai_addr
указывает на
struct sockaddr
для соответствующего протокола. Например, если
ai_family
принимает значение
PF_INET
, то
ai_addr
указывает на
struct sockaddr_in
. Член
ai_addrlen
определяет длину структуры, на которую указывает
ai_addr
.

• Если предусмотрен параметр

servicename
, то в качестве номера порта в каждом адресе устанавливается официальный порт данной службы. В противном случае номер порта для каждого адреса равен нулю.

• Если не был передан параметр

hostname
, то номера портов устанавливаются для каждого адреса, однако в качестве IP-адреса определяется или адрес обратной связи, или неустановленный адрес (как указывалось ранее в описании флага
AI_PASSIVE
).

Все это может показаться достаточно запутанным. На самом деле, существует только два различных способа стандартного применения функции

getaddrinfo
. Большинство клиентских программ стремятся превратить имя хоста, передаваемое пользователем, и имя службы, известное программе, в полностью определенный адрес, с которым пользователь может установить соединение. Достичь этой цели нетрудно. Ниже приводится программа, которая принимает имя хоста как первый аргумент и имя службы как второй, после чего выполняет все необходимые преобразования.

 1: /* clientlookup.c */

 2:

 3: #include <netdb.h>

 4: #include <stdio.h>

 5: #include <string.h>

 6:

 7: int main(int argc, const char ** argv) {

 8: struct addrinfo hints, * addr;

 9: const char * host = argv[1], * service = argv[2];

10: int rc;

11:

12: if (argc != 3) {

13: fprintf(stderr, "требуется в точности два аргумента\n");

14: return 1;

15: }

16:

17: memset(&hints, 0, sizeof(hints));

18:

19: hints.ai_socktype = SOCK_STREAM;

20: hints.ai_flags = AI_ADDRCONFIG;

21: if ((rc = getaddrinfo(host, service, &hints, &addr)))

22: fprintf(stderr, "сбой поиска\n");

23: else

24: freeaddrinfo(addr);

25:

26: return 0;

27: }

Давайте обратим внимание на строки 17–24 этой программы. После очистки структуры hints приложение запрашивает адреса

SOCK_STREAM
, которые используют протокол, сконфигурированный на локальной системе (путем установки флага
AI_ADDRCONFIG
). Затем активизируется функция
getaddrinfo
с именем хоста, именем службы, подсказками и в случае невозможности найти соответствие отображается сообщение об ошибке. Если все проходит нормально, то первый элемент в связном списке, на который указывает
addr
, представляет собой соответствующий адрес, который программа может использовать для установки соединения с указанной службой и хостом. Программа не решает, через какой протокол (IPv4 или IPv6) соединение будет лучшим.

Серверные приложения немного проще. В них, как правило, требуется согласиться на соединение с определенным портом, при этом на всех адресах. Если установлены флаги

AI_PASSIVE
, функция
getaddrinfo
возвращает адрес, вынуждающий ядро разрешать все соединения (со всеми адресами, которые оно знает) при условии, что в качестве первого параметра передается
NULL
. Как и в клиентском примере, используется
AI_ADDRCONFIG
, дабы убедиться, что возвращаемый адрес соответствует протоколу, который поддерживает данная машина.

  • Читать дальше
  • 1
  • ...
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: