11.17. Функция getnameinfo

11.17. Функция getnameinfo

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

#include <netdb.h>

int getnameinfo(const struct sockaddr *sockaddr, socklen_t addrlen, char *host,

 size_t hostlen, char *serv, size_t servlen, int flags);

Возвращает 0 в случае успешного выполнения, -1 в случае ошибки

Аргумент sockaddr указывает на структуру адреса сокета, содержащую адрес протокола, преобразуемый в строку, удобную для человеческого восприятия, а аргумент addrlen содержит длину этой структуры. Эта структура и ее длина обычно возвращаются любой из следующих функций: accept, recvfrom, getsockname или getpeername.

Вызывающий процесс выделяет в памяти пространство для двух строк, удобных для человеческого восприятия: аргументы host и hostlen определяют строку, описывающую узел, а аргументы serv и servlen определяют строку, которая описывает службы. Если вызывающему процессу не нужна возвращаемая строка с описанием узла, задается нулевая длина этой строки (hostlen). Аналогично, нулевое значение аргумента servlen означает, что не нужно возвращать информацию о службе.

Разница между функциями sock_ntop и getnameinfo состоит в том, что первая не задействует DNS, а только возвращает IP-адрес и номер порта. Последняя же обычно пытается получить имя и для узла, и для службы.

В табл. 11.4 показаны шесть флагов, которые можно задать для изменения действия, выполняемого функцией getnameinfo.

Таблица 11.4. Флаги функции getnameinfo

Константа Описание NI_DGRAM Дейтаграммный сокет NI_NAMEREQD Возвращать ошибку, если невозможно получить имя узла по его адресу NI_NOFQDN Возвращать только ту часть FQDN, которая содержит имя узла NI_NUMERICHOST Возвращать численное значение адреса вместо имени узла NI_NUMERICSCOPE Возвращать численное значение идентификатора области NI_NUMERICSERV Возвращать номер порта вместо имени службы

? Флаг NI_DGRAM должен быть задан, когда вызывающий процесс знает, что работает с дейтаграммным сокетом. Причина в том, что если функции getnameinfo задать только IP-адрес и номер порта в структуре адреса сокета, она не сможет определить протокол (TCP или UDP). Существует несколько номеров портов, которые в случае TCP задействованы для одной службы, а в случае UDP для совершенно другой. Примером может служить порт 514, используемый службой rsh в TCP и службой syslog в UDP.

? Флаг NI_NAMEREQD приводит к возвращению ошибки, если имя узла не может быть разрешено при использовании DNS. Этот флаг может использоваться серверами, которым требуется, чтобы IP-адресу клиента было сопоставлено имя узла. Затем эти серверы получают возвращаемое имя узла, вызывают функцию gethostbyname и проверяют, совпадают ли результаты вызова этих двух функций хотя бы частично.

? Флаг NI_NOFQDN вызывает сокращение имени узла, отбрасывая все, что идет после первой точки. Например, если в структуре адреса сокета содержится IP-адрес 192.168.42.2, то функция gethostbyaddr возвратит имя aix.unpbook.com. Но если в функции getnameinfo задан флаг NI_NOFQDN, она возвратит в имени узла только aix.

? Флаг NI_NUMERICHOST сообщает функции getnameinfo, что не нужно вызывать DNS (поскольку это занимает некоторое время). Вместо этого возвращается численное представление IP-адреса, вероятно, при помощи вызова функции inet_ntop. Аналогично, флаг NI_NUMERICSERV определяет, что вместо имени службы должен быть возвращен десятичный номер порта. Обычно серверы должны задавать этот флаг, поскольку номера портов клиента, как правило, не имеют соответствующего имени службы — это динамически назначаемые порты. NI_NUMERICSCOPE указывает на необходимость возвращения идентификатора области в численном, а не в текстовом виде.

Можно объединять несколько флагов путем логического сложения, если их сочетание имеет смысл, например NI_DGRAM и NI_NUMERICHOST.

Данный текст является ознакомительным фрагментом.