Преобразование имен узлов и служб в двоичный вид и обратно

Функция getaddrinfo() является современным аналогом устаревших функций gethostbyname() и getservbyname(). Если передать ей имена узла и службы, то она вернет набор структур, содержащих соответствующие IP-адреса (их может быть несколько) и номер порта в двоичном виде. В отличие от gethostbyname(), функция getaddrinfo() умеет прозрачно работать с адресами в форматах IPv4 и IPv6, поэтому ее можно использовать для написания программ, которые не зависят от версии протокола IP. Данную функцию следует применять во всех новых программах для преобразования имен узлов и служб в двоичное представление.

Функция getnameinfo() выполняет обратное преобразование, превращая IP-адрес и номер порта в соответствующие имена узла и службы.

С помощью функций getaddrinfo() и getnameinfo() можно также переводить IP-адрес в презентационный формат и обратно.

Прежде чем приступать к подробному обсуждению этих функций в разделе 55.10, сначала необходимо рассмотреть службу DNS (см. раздел 55.8) и файл /etc/services (см. раздел 55.9). DNS позволяет совместно работающим серверам обслуживать распределенные базы данных, которые привязывают IP-адреса к именам узлов и наоборот. Существование таких служб, как DNS, необходимо для работы Интернета, поскольку централизованное управление всеми существующими именами узлов было бы попросту невозможным. Файл /etc/services привязывает номера портов к символьным именам служб.

55.6. Функции inet_pton() и inet_ntop()

Функции inet_pton() и inet_ntop() позволяют преобразовывать IPv4- и IPv6-адреса между двоичным и презентационным (десятичные числа, разделенные точками, или шестнадцатеричная строка) форматами. Буква p в именах этих функций обозначает presentation («презентационный»), а n — network («сеть»).

#include

int inet_pton(int domain, const char *src_str, void *addrptr);

Возвращает 1 при успешном завершении, 0, если строка src_str не соответствует презентационному формату, или -1 при ошибке

const char *inet_ntop(int domain, const void *addrptr, char *dst_str,

size_t len);

Возвращает указатель на dst_str или NULL при ошибке

Презентационный вид представляет собой строку, понятную для человека. Например:

• 204.152.189.116 (IPv4-адрес в виде десятичных чисел, разделенных точками);

•::1 (IPv6-адрес в виде шестнадцатеричных значений, разделенных двоеточиями);

•::FFFF:204.152.189.116 (IPv4-адрес, совместимый с IPv6).

Функция inet_pton() переводит презентационную строку, переданную в аргументе src_str, в двоичный IP-адрес с сетевым порядком следования байтов. Аргумент domain должен быть равен AF_INET или AF_INET6. Полученный адрес помещается в структуру, на которую указывает аргумент addrptr; тип структуры должен быть либо in_addr, либо in6_addr, в зависимости от значения domain.

Функция inet_ntop() выполняет обратное преобразование. Повторим: аргумент domain должен быть равен AF_INET или AF_INET6, а указатель addrptr должен ссылаться на структуру типа in_addr или in6_addr, которую мы хотим преобразовать. Итоговая строка с нулевым символом в конце помещается в буфер, на который указывает dst_str. Аргумент len должен содержать размер этого буфера. В случае успеха функция inet_ntop() возвращает dst_str. Если размер len слишком маленький, то inet_ntop() возвращает NULL, а глобальной переменной errno присваивается ENOSPC.

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

#define INET_ADDRSTRLEN 16 /* Максимальный размер строки с десятичными числами,

разделенными точками (IPv4) */

#define INET6_ADDRSTRLEN 46 /* Максимальный размер шестнадцатеричной строки (IPv6) */

Примеры использования inet_pton() и inet_ntop() приведены в следующем разделе.

55.7. Пример клиент-серверного приложения (на основе датаграммных сокетов)

В этом разделе мы возьмем клиентскую и серверную программы для изменения регистра, показанные в разделе 53.3, и перепишем их с учетом использования датаграммных сокетов в домене AF_INET6. Исходный код будет представлен с минимальными комментариями, поскольку по своей структуре он похож на ранее рассмотренные программы. Главное отличие новой версии заключается в определении и инициализации структуры с адресом сокета в формате IPv6, которую мы описали в разделе 55.4.

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

Перейти на страницу:

Похожие книги