Поделиться через


Функция gethostbyaddr (winsock.h)

[Gethostbyaddr больше не рекомендуется использовать в сокетах Windows 2. Вместо этого используйте getnameinfo.]

Функция gethostbyaddr извлекает сведения об узле, соответствующие сетевому адресу.

Синтаксис

hostent * gethostbyaddr(
  const char *addr,
  int        len,
  int        type
);

Параметры

addr

TBD

len

TBD

type

TBD

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

Если ошибки не произошло, gethostbyaddr возвращает указатель на структуру узла . В противном случае возвращается пустой указатель, и конкретный код ошибки можно получить, вызвав WSAGetLastError.

Код ошибки Значение
WSANOTINITIALISED
Перед использованием этой функции должен быть выполнен успешный вызов WSAStartup .
WSAEINVAL
Указан недопустимый аргумент. Эта ошибка возвращается, если AF_INET6 была указана в параметре type , а параметр len не был равен размеру IPv6-адреса.
WSAENETDOWN
Произошел сбой сетевой подсистемы.
WSAHOST_NOT_FOUND
Достоверный узел ответа не найден.
WSATRY_AGAIN
Неавторитативный узел не найден или произошел сбой сервера.
WSANO_RECOVERY
Произошла неустранимая ошибка.
WSANO_DATA
Допустимое имя, нет записи данных запрошенного типа.
WSAEINPROGRESS
Выполняется блокирующий вызов Windows Sockets 1.1 или поставщик услуг по-прежнему обрабатывает функцию обратного вызова.
WSAEAFNOSUPPORT
Указанный тип не поддерживается реализацией сокетов Windows.
WSAEFAULT
Параметр addr не является допустимой частью адресного пространства пользователя или параметр len слишком мал.
WSAEINTR
Блокирующий вызов сокета Windows 1.1 был отменен через WSACancelBlockingCall.

Комментарии

Функция gethostbyaddr возвращает указатель на структуру узла , содержащую имя и адрес, соответствующие заданному сетевому адресу.

Память для структуры размещения , возвращаемой функцией gethostbyaddr , выделяется внутренне библиотекой DLL Winsock из локального хранилища потока. Выделяется и используется только одна структура узла , независимо от того, сколько раз функции gethostbyaddr или gethostbyname вызываются в потоке. Возвращаемая структура узла должна быть скопирована в буфер приложения, если необходимо выполнить дополнительные вызовы функций gethostbyaddr или gethostbyname в том же потоке. В противном случае возвращаемое значение будет перезаписан последующими вызовами gethostbyaddr или gethostbyname в том же потоке. Внутренняя память, выделенная для возвращаемой структуры размещения , освобождается библиотекой DLL Winsock при выходе потока.

Приложение не должно пытаться освободить память, используемую возвращаемой структурой размещения . Приложение никогда не должно пытаться изменить эту структуру или освободить какие-либо из ее компонентов. Кроме того, для каждого потока выделяется только одна копия этой структуры, поэтому приложение должно скопировать все необходимые сведения перед выполнением других вызовов функций gethostbyaddr или gethostbyname.

Хотя gethostbyaddr больше не рекомендуется использовать в сокетах Windows 2 и следует использовать функцию getnameinfo , gethostbyaddr может возвращать netBIOS-имя; Getnameinfo не имеет значение . Разработчикам, которым требуется разрешение имен NetBIOS, может потребоваться использовать gethostbyaddr , пока их приложения не будут полностью независимы от NetBIOS-имен.

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

Пример кода

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

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

    //-----------------------------------------
    // Declare and initialize variables
    WSADATA wsaData;
    int iResult;

    DWORD dwError;
    int i = 0;
    int bIpv6 = 0;

    struct hostent *remoteHost;
    char *host_addr;
    struct in_addr addr = { 0 };
    IN6_ADDR addr6;

    char **pAlias;

    // Validate the parameters
    if (argc < 2) {
        printf("usage: %s 4 ipv4address\n", argv[0]);
        printf(" or\n");
        printf("usage: %s 6 ipv6address\n", argv[0]);
        printf("  to return the hostname\n");
        printf("       %s 4 127.0.0.1\n", argv[0]);
        printf("       %s 6 0::1\n", argv[0]);
        return 1;
    }
    // Validate parameters 
    if (atoi(argv[1]) == 4)
        bIpv6 = 0;
    else if (atoi(argv[1]) == 6)
        bIpv6 = 1;
    else {
        printf("usage: %s 4 ipv4address\n", argv[0]);
        printf(" or\n");
        printf("usage: %s 6 ipv6address\n", argv[0]);
        printf("  to return the hostname\n");
        printf("       %s 4 127.0.0.1\n", argv[0]);
        printf("       %s 6 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;
    }

    host_addr = argv[2];

    printf("Calling gethostbyaddr with %s\n", host_addr);
    if (bIpv6 == 1) {
        {
            iResult = inet_pton(AF_INET6, host_addr, &addr6);
            if (iResult == 0) {
                printf("The IPv6 address entered must be a legal address\n");
                return 1;
            } else
                remoteHost = gethostbyaddr((char *) &addr6, 16, AF_INET6);
        }
    } else {
        addr.s_addr = inet_addr(host_addr);
        if (addr.s_addr == INADDR_NONE) {
            printf("The IPv4 address entered must be a legal address\n");
            return 1;
        } else
            remoteHost = gethostbyaddr((char *) &addr, 4, AF_INET);
    }

    if (remoteHost == NULL) {
        dwError = WSAGetLastError();
        if (dwError != 0) {
            if (dwError == WSAHOST_NOT_FOUND) {
                printf("Host not found\n");
                return 1;
            } else if (dwError == WSANO_DATA) {
                printf("No data record found\n");
                return 1;
            } else {
                printf("Function failed with error: %ld\n", dwError);
                return 1;
            }
        }
    } else {
        printf("Function returned:\n");
        printf("\tOfficial name: %s\n", remoteHost->h_name);
        for (pAlias = remoteHost->h_aliases; *pAlias != 0; pAlias++) {
            printf("\tAlternate name #%d: %s\n", ++i, *pAlias);
        }
        printf("\tAddress type: ");
        switch (remoteHost->h_addrtype) {
        case AF_INET:
            printf("AF_INET\n");
            break;
        case AF_INET6:
            printf("AF_INET6\n");
            break;
        case AF_NETBIOS:
            printf("AF_NETBIOS\n");
            break;
        default:
            printf(" %d\n", remoteHost->h_addrtype);
            break;
        }
        printf("\tAddress length: %d\n", remoteHost->h_length);

        if (remoteHost->h_addrtype == AF_INET) {
            while (remoteHost->h_addr_list[i] != 0) {
                addr.s_addr = *(u_long *) remoteHost->h_addr_list[i++];
                printf("\tIPv4 Address #%d: %s\n", i, inet_ntoa(addr));
            }
        } else if (remoteHost->h_addrtype == AF_INET6)
            printf("\tRemotehost is an IPv6 address\n");
    }

    return 0;
}

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 winsock.h (включая Winsock2.h, Winsock.h)
Библиотека Ws2_32.lib
DLL Ws2_32.dll

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

GetAddrInfoEx

GetAddrInfoW

WSAsyncGetHostByAddr

Функции Winsock

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

addrinfo

addrinfoW

getaddrinfo

Gethostbyname

hostent