Чтение онлайн

на главную - закладки

Жанры

Разработка приложений в среде Linux. Второе издание

Троан Эрик В.

Шрифт:

142: nameBuf, sizeof(nameBuf)));

143: }

Обратное преобразование строки, содержащей адрес с точками или двоеточиями, в двоичный IP-адрес выполняет функция

inet_pton
.

#include <arpa/inet.h>

int inet_pton(int family, const char * address, void * dest);

Параметр

family
определяет тип преобразуемого адреса (либо
AF_INET
, либо
AF_INET6
), a
address
указывает на строку, в которой содержится символьное представление адреса. Если используется
AF_INET
, то десятичная строка с
точками преобразуется в двоичный адрес, хранящийся в переменной, на которую указывает параметр
dest
структуры
struct in_addr
. Для
AF_INET6
строка с двоеточиями преобразуется и сохраняется в переменной, на которую указывает
dest
структуры
struct in6_addr
. В отличие от большинства библиотечных функций,
inet_pton
возвращает
1
, если преобразование прошло успешно,
0
, если
dest
не содержит соответствующий адрес, и
– 1
, если параметр
family
не совпадает с
AF_INET
или
AF_INET6
.

Программа-пример

reverselookup
, код которой представлен далее в главе, использует функцию
inet_pton
для преобразования IPv4- и IPv6-адресов, передаваемых пользователем, в структуры
struct sockaddr
. Ниже приводится раздел кода, выполняющий преобразования IP-адреса, на который указывает
hostAddress
. В конце данного кода
struct sockaddr * addr
указывает на структуру, содержащую преобразованный адрес.

 79: if (!hostAddress) {

 80: addr4.sin_family = AF_INET;

 81: addr4.sin_port = portNum;

 82: } else if (! strchr(hostAddress, ':')) {

 83: /* Если в hostAddress появляется двоеточие, то принимаем версию IPv6.

 84: В противном случае это IPv4-адрес */

 85:

 86: if (inet_pton(AF_INET, hostAddress,

 87: &addr4.sin_addr) <= 0) {

 88: fprintf(stderr, "ошибка преобразования IPv4-адреса %s\n",

 89: hostAddress);

 90: return 1;

 91: }

 92:

 93: addr4.sin_family = AF_INET;

 94: addr4.sin_port = portNum;

 95: } else {

 96:

 97: memset(&addr6, 0, sizeof(addr6));

 98:

 99: if (inet_pton(AF_INET6, hostAddress,

100: &addr6.sin6_addr) <= 0) {

101: fprintf(stderr, "ошибка преобразования IPv6-адреса %s\n",

102: hostAddress);

103: return 1;

104: }

105:

106: addr6.sin6_family = AF_INET6;

107: addr6.sin6_port = portNum;

108: addr = (struct sockaddr *) &addr6;

109: addrLen = sizeof(addr6);

110: }

17.5.5. Преобразование имен в адреса

Длинные последовательности чисел являются отлично подходящим методом идентификации для компьютеров, позволяющим им однозначно узнавать друг друга. Однако большинство людей охватывает ужас при мысли о том, что придется иметь дело с большим количеством цифр. Для того чтобы разрешить людям применять текстовые названия для компьютеров вместо числовых, в состав протоколов TCP/IP входит распределенная

база данных для взаимных преобразований имен хостов и IP-адресов. Эта база данных называется DNS (Domain Name System — служба имен доменов), она подробно рассматривается в [34] и [1].

Служба DNS предлагает много функций, но сейчас нас интересует одна — возможность преобразования IP-адресов в имена хостов и наоборот. Несмотря на то что это преобразование должно выполняться как однозначное соответствие, на самом деле оно представляет собой отношение типа "многие ко многим". Другими словами, каждый IP-адрес может соответствовать нулю или более именам хостов, а каждое имя хоста соответствует нулю или более IP-адресам.

Использование неоднозначного соответствия между именами хостов и IP-адресами может показаться странным. Однако многие Internet-сайты применяют одну и ту же машину для ftp-сайта и Web-сайта. При этом адреса

www.some.org
и
ftp.some.org
должны ссылаться на одну и ту же машину, а для одной машины не нужны два IP-адреса. Таким образом, два имени хостов сводятся к одному IP-адресу. Каждый IP-адрес имеет одно первичное, или каноническое имя хоста, которое используется, если IP-адрес требуется преобразовать в единственное имя хоста во время обратного поиска имен.

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

Появление IPv6 повлекло за собой еще одну причину, по которой одно имя хоста должно иметь несколько адресов. Многие машины сейчас имеют одновременно и IPv4-, и IPv6-адреса.

Библиотечная функция

getaddrinfo
[134] предлагает программам простой доступ к преобразованиям имен хостов DNS.

#include <sys/types.h>

#include <socket.h>

#include <netdb.h>

int getaddrinfo(const char * hostname, const char * servicename,

 const struct addrinfo * hints, struct addrinfo ** res);

Концепция этой функции достаточно простая, однако весьма мощная, в связи с этим ее описание может показаться несколько запутанным. Идея заключается в том, что функция принимает имя хоста, имя службы (или оба из них) и превращает их в список IP-адресов. Затем с использованием

hints
список фильтруется и те адреса, которые не нужны приложению, отбрасываются. Окончательный список возвращается в виде связного списка в переменной
res
.

134

Если у вас большой опыт в программировании сокетов (или вы сравниваете данную книгу с ее первым изданием), то вы обязательно заметите, что функции, применявшиеся для преобразования имен, значительно изменились. Эти изменения позволяют создавать программы абсолютно независимо от того протокола, который они используют. Теперь гораздо легче разрабатывать программы, работающие как на IPv4-, так и на IPv6-машинах. Они также должны распространяться на остальные протоколы, хотя функция

getaddrinfo
в данный момент работает только для IPv4 и IPv6.

Искомое имя хоста содержится в первом параметре и может равняться

NULL
, если производится поиск только службы. Параметр
hostname
может быть именем (например,
www.ladweb.net
) или IP-адресом (с точками или двоеточиями в качестве разделителей), который функция
getaddrinfo
преобразует в двоичный адрес.

Второй параметр

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

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

Камень Книга седьмая

Минин Станислав
7. Камень
Фантастика:
фэнтези
боевая фантастика
6.22
рейтинг книги
Камень Книга седьмая

Я сделаю это сама

Кальк Салма
1. Магический XVIII век
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Я сделаю это сама

Кровь на эполетах

Дроздов Анатолий Федорович
3. Штуцер и тесак
Фантастика:
альтернативная история
7.60
рейтинг книги
Кровь на эполетах

Сыночек в награду. Подари мне любовь

Лесневская Вероника
1. Суровые отцы
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Сыночек в награду. Подари мне любовь

Кодекс Крови. Книга ХII

Борзых М.
12. РОС: Кодекс Крови
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Кодекс Крови. Книга ХII

Найди меня Шерхан

Тоцка Тала
3. Ямпольские-Демидовы
Любовные романы:
современные любовные романы
короткие любовные романы
7.70
рейтинг книги
Найди меня Шерхан

Идеальный мир для Лекаря 4

Сапфир Олег
4. Лекарь
Фантастика:
фэнтези
юмористическая фантастика
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 4

Релокант. По следам Ушедшего

Ascold Flow
3. Релокант в другой мир
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Релокант. По следам Ушедшего

Мир-о-творец

Ланцов Михаил Алексеевич
8. Помещик
Фантастика:
альтернативная история
5.00
рейтинг книги
Мир-о-творец

Протокол "Наследник"

Лисина Александра
1. Гибрид
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Протокол Наследник

Кодекс Охотника. Книга VII

Винокуров Юрий
7. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
4.75
рейтинг книги
Кодекс Охотника. Книга VII

Попаданка в семье драконов

Свадьбина Любовь
Попаданка в академии драконов
Любовные романы:
любовно-фантастические романы
7.37
рейтинг книги
Попаданка в семье драконов

Новые горизонты

Лисина Александра
5. Гибрид
Фантастика:
попаданцы
технофэнтези
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Новые горизонты

Скрываясь в тени

Мазуров Дмитрий
2. Теневой путь
Фантастика:
боевая фантастика
7.84
рейтинг книги
Скрываясь в тени