Функция getnameinfo (ws2tcpip.h)

Функция getnameinfo обеспечивает независимое от протокола разрешение имен от адреса до имени узла ANSI и от номера порта до имени службы ANSI.

Синтаксис

INT WSAAPI getnameinfo(
  [in]  const SOCKADDR *pSockaddr,
  [in]  socklen_t      SockaddrLength,
  [out] PCHAR          pNodeBuffer,
  [in]  DWORD          NodeBufferSize,
  [out] PCHAR          pServiceBuffer,
  [in]  DWORD          ServiceBufferSize,
  [in]  INT            Flags
);

Параметры

[in] pSockaddr

Указатель на структуру адресов сокета, содержащую адрес и номер порта сокета. Для IPv4 параметр sa указывает на структуру sockaddr_in . Для IPv6 параметр sa указывает на sockaddr_in6 структуру.

[in] SockaddrLength

Длина (в байтах) структуры, на которую указывает параметр sa .

[out] pNodeBuffer

Указатель на строку ANSI, используемую для хранения имени узла. При успешном выполнении имя узла по умолчанию возвращается как полное доменное имя (FQDN). Если параметр узла имеет значение NULL, это означает, что вызывающий объект не хочет получать строку имени узла.

[in] NodeBufferSize

Длина (в байтах) буфера, на который указывает параметр узла . Вызывающий объект должен предоставить буфер, достаточно большой для хранения имени узла, включая завершающий символ NULL .

[out] pServiceBuffer

Указатель на строку ANSI для хранения имени службы. При успешном выполнении возвращается строка ANSI, представляющая имя службы, связанной с номером порта. Если параметр serv имеет значение NULL, это означает, что вызывающий объект не хочет получать строку имени службы.

[in] ServiceBufferSize

Длина (в байтах) буфера, на который указывает параметр serv . Вызывающий объект должен предоставить буфер, достаточно большой для хранения имени службы, включая завершающий символ NULL .

[in] Flags

Значение, используемое для настройки обработки функции getnameinfo . См. раздел «Примечания».

Возвращаемое значение

При успешном выполнении getnameinfo возвращает ноль. Любое ненулевое возвращаемое значение указывает на сбой, и конкретный код ошибки можно получить, вызвав WSAGetLastError.

Коды ненулевых ошибок, возвращаемые функцией getnameinfo , также сопоставляются с набором ошибок, описанных в рекомендациях Internet Engineering Task Force (IETF). В следующей таблице перечислены эти коды ошибок и их эквиваленты WSA. Рекомендуется использовать коды ошибок WSA, так как они предоставляют знакомые и исчерпывающие сведения об ошибках для программистов Winsock.

Значение ошибки Эквивалент WSA Описание
EAI_AGAIN WSATRY_AGAIN Произошла временная ошибка разрешения имен.
EAI_BADFLAGS WSAEINVAL В функцию getnameinfo был передан один или несколько недопустимых параметров. Эта ошибка возвращается, если было запрошено имя узла, но параметр hostlen был равен нулю или если было запрошено имя службы, но параметр servlen равен нулю.
EAI_FAIL WSANO_RECOVERY Произошел неустранимый сбой при разрешении имен.
EAI_FAMILY WSAEAFNOSUPPORT Элемент sa_family структуры адресов сокета, на который указывает параметр sa , не поддерживается.
EAI_MEMORY WSA_NOT_ENOUGH_MEMORY Произошел сбой выделения памяти.
EAI_NONAME WSAHOST_NOT_FOUND Запрошено имя службы, но в структуре, на которую указывает параметр sa , не найден номер порта, или не найдено имя службы, соответствующее номеру порта. NI_NAMEREQD задано и не удается найти имя узла, или параметры узла и serv имели значение NULL.
 

Используйте функцию gai_strerror для вывода сообщений об ошибках на основе кодов EAI, возвращаемых функцией getnameinfo . Функция gai_strerror предоставляется для соответствия рекомендациям IETF, но не является потокобезопасной. Поэтому рекомендуется использовать традиционные функции сокетов Windows, такие как WSAGetLastError .

Кроме того, можно вернуть следующие коды ошибок.

Код ошибки Значение
WSAEFAULT
Эта ошибка возвращается, если параметр sa имеет значение NULL или параметр salen меньше длины, необходимой для размера структуры sockaddr_in для IPv4 или структуры sockaddr_in6 для IPv6.

Комментарии

Функция getnameinfo — это версия ANSI функции, которая обеспечивает независимое от протокола разрешение имен. Функция getnameinfo используется для преобразования содержимого структуры адресов сокета в имя узла и (или) имя службы.

Для протоколов IPv6 и IPv4 разрешение имен может осуществляться системой доменных имен (DNS), локальным файлом узлов или другими механизмами именования. Эта функция может использоваться для определения имени узла для адреса IPv4 или IPv6, обратного поиска DNS или определения имени службы для номера порта. Функцию getnameinfo также можно использовать для преобразования IP-адреса или номера порта в структуре sockaddr в строку ANSI. Эта функция также может использоваться для определения IP-адреса для имени узла.

Другое имя, которое можно использовать для функции getnameinfo , — GetNameInfoA. Макросы в файле заголовка Ws2tcpip.h определяют GetNameInfoA для getnameinfo.

Версия этой функции в Юникоде, доступная в Windows XP с пакетом обновления 2 (SP2) и более поздних версий, — GetNameInfoW.

Макросы в файле заголовка Winsock определяют имя функции GetNameInfo в смешанном регистре, которое можно использовать, когда приложение предназначено для Windows XP с пакетом обновления 2 (SP2) и более поздних версий (_WIN32_WINNT >= 0x0502). Эта функция GetNameInfo должна вызываться с параметрами host и serv указателя типа TCHAR. Если юникод или _UNICODE не определены, GetNameInfo определяется для версии ANSI, а getnameinfo вызывается с параметрами узла и службы указателя типа char. При определении ЮНИКОДа или _UNICODE getNameInfo определяется для версии Юникода, а GetNameInfoW вызывается с параметрами pNodeBuffer и pServiceBuffer указателя типа PWCHAR.

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

#define NI_MAXSERV    32
#define NI_MAXHOST  1025

Параметр flags можно использовать для настройки обработки функции getnameinfo . Доступны следующие флаги:

  • NI_NOFQDN
  • NI_NUMERICHOST
  • NI_NAMEREQD
  • NI_NUMERICSERV
  • NI_DGRAM

Если установлен флаг NI_NAMEREQD , имя узла, которое не может быть разрешено DNS, приводит к ошибке.

Установка флага NI_NOFQDN приводит к тому, что локальные узлы возвращают только их относительное различающееся имя (RDN) в параметре узла .

При установке флага NI_NUMERICHOST возвращается числовая форма имени узла, а не его имя. Числовая форма имени узла также возвращается, если имя узла не может быть разрешено DNS.

При установке флага NI_NUMERICSERV возвращается номер порта службы, а не ее имя. Кроме того, если имя узла не найдено для IP-адреса (например, 127.0.0.2), имя узла возвращается в качестве IP-адреса.

В Windows Vista и более поздних версиях, если NI_NUMERICSERV не указан в параметре flags , а номер порта, содержащийся в структуре sockaddr, на которую указывает параметр sa , не разрешается в хорошо известную службу, функция getnameinfo возвращает числовую форму адреса службы (номер порта) в виде числовой строки. При указании NI_NUMERICSERV номер порта возвращается в виде числовой строки. Это поведение указано в разделе 6.2 RFC 3493. Дополнительные сведения см. в разделе www.ietf.org/rfc3493.txt

В Windows Server 2003 и более ранних версиях, если NI_NUMERICSERV не указан в параметре flags , а номер порта, содержащийся в структуре sockaddr , на которую указывает параметр sa , не разрешается в хорошо известную службу, функция getnameinfo завершается ошибкой. При указании NI_NUMERICSERV номер порта возвращается в виде числовой строки.

Установка флага NI_DGRAM означает, что служба является службой датаграмм. Этот флаг необходим для нескольких служб, которые предоставляют разные номера портов для службы UDP и TCP.

Примечание Возможность выполнять обратный поиск DNS с помощью функции getnameinfo удобна, но такие запросы считаются ненадежными по своей сути и должны использоваться только в качестве указания.
 
Примечание Функцию getnameinfo нельзя использовать для разрешения имен псевдонимов.
 

Пример кода

В следующем примере кода показано, как использовать функцию getnameinfo .
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>

// link with ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")

int __cdecl main(int argc, char **argv)
{

    //-----------------------------------------
    // Declare and initialize variables
    WSADATA wsaData = {0};
    int iResult = 0;

    DWORD dwRetval;

    struct sockaddr_in saGNI;
    char hostname[NI_MAXHOST];
    char servInfo[NI_MAXSERV];
    u_short port = 27015;

    // Validate the parameters
    if (argc != 2) {
        printf("usage: %s IPv4 address\n", argv[0]);
        printf("  to return hostname\n");
        printf("       %s 127.0.0.1\n", argv[0]);
        return 1;
    }
    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0) {
        printf("WSAStartup failed: %d\n", iResult);
        return 1;
    }
    //-----------------------------------------
    // Set up sockaddr_in structure which is passed
    // to the getnameinfo function
    saGNI.sin_family = AF_INET;
    saGNI.sin_addr.s_addr = inet_addr(argv[1]);
    saGNI.sin_port = htons(port);

    //-----------------------------------------
    // Call getnameinfo
    dwRetval = getnameinfo((struct sockaddr *) &saGNI,
                           sizeof (struct sockaddr),
                           hostname,
                           NI_MAXHOST, servInfo, NI_MAXSERV, NI_NUMERICSERV);

    if (dwRetval != 0) {
        printf("getnameinfo failed with error # %ld\n", WSAGetLastError());
        return 1;
    } else {
        printf("getnameinfo returned hostname = %s\n", hostname);
        return 0;
    }
}

Поддержка getnameinfo в более ранних версиях Windows

Функция getnameinfo была добавлена в Ws2_32.dll в Windows XP и более поздних версий. Если вы хотите выполнить приложение с помощью этой функции в более ранних версиях Windows (Windows 2000, Windows NT и Windows Me/98/95), необходимо включить файл Ws2tcpip.h, а также Wspiapi.h. При добавлении включаемого файла Wspiapi.h функция getnameinfo определяется для встроенной функции WspiapiGetNameInfo в файле Wspiapi.h . Во время выполнения функция WspiapiGetNameInfo реализована таким образом, что если Ws2_32.dll или Wship6.dll (файл, содержащий getnameinfo в предварительной версии технологии IPv6 для Windows 2000) не включает getnameinfo, то версия getnameinfo реализуется встроенно на основе кода в файле заголовка Wspiapi.h . Этот встроенный код будет использоваться на старых платформах Windows, которые изначально не поддерживают функцию getnameinfo .

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

Функция GetNameInfoW — это версия getnameinfo в Юникоде. Функция GetNameInfoW была добавлена в Ws2_32.dll в Windows XP с пакетом обновления 2 (SP2). Функцию GetNameInfoW нельзя использовать в версиях Windows, предшествующих Windows XP с пакетом обновления 2 (SP2).

Windows Phone 8. Эта функция поддерживается для приложений Магазина Windows Phone Windows Phone 8 и более поздних версий.

Windows 8.1 и Windows Server 2012 R2. Эта функция поддерживается для приложений Магазина Windows в Windows 8.1, Windows Server 2012 R2 и более поздних версий.

Требования

Требование Значение
Минимальная версия клиента Windows 8.1, Windows Vista [классические приложения | Приложения UWP]
Минимальная версия сервера Windows Server 2003 [классические приложения | Приложения UWP]
Целевая платформа Windows
Header ws2tcpip.h
Библиотека Ws2_32.lib
DLL Ws2_32.dll

См. также раздел

GetNameInfoW

WSAGetLastError

Функции Winsock

Справочник по Winsock

gai_strerror

getaddrinfo

sockaddr