getaddrinfo 함수(ws2tcpip.h)

getaddrinfo 함수는 ANSI 호스트 이름에서 주소로 프로토콜 독립적 변환을 제공합니다.

구문

INT WSAAPI getaddrinfo(
  [in, optional] PCSTR           pNodeName,
  [in, optional] PCSTR           pServiceName,
  [in, optional] const ADDRINFOA *pHints,
  [out]          PADDRINFOA      *ppResult
);

매개 변수

[in, optional] pNodeName

호스트(노드) 이름 또는 숫자 호스트 주소 문자열을 포함하는 NULL로 종료된 ANSI 문자열에 대한 포인터입니다. 인터넷 프로토콜의 경우 숫자 호스트 주소 문자열은 점선 10진수 IPv4 주소 또는 IPv6 16진수 주소입니다.

[in, optional] pServiceName

문자열로 표시되는 서비스 이름 또는 포트 번호를 포함하는 NULL로 종료된 ANSI 문자열에 대한 포인터입니다.

서비스 이름은 포트 번호의 문자열 별칭입니다. 예를 들어 "http"는 IETF(인터넷 엔지니어링 태스크 포스)에서 HTTP 프로토콜에 대해 웹 서버에서 사용하는 기본 포트로 정의된 포트 80의 별칭입니다. 포트 번호를 지정하지 않은 경우 pServiceName 매개 변수에 대한 가능한 값은 다음 파일에 나열됩니다.

%WINDIR%\system32\drivers\etc\services

[in, optional] pHints

호출자가 지원하는 소켓 유형에 대한 힌트를 제공하는 addrinfo 구조체에 대한 포인터입니다.

pHints 매개 변수가 가리키는 addrinfo 구조체의 ai_addrlen,ai_canonname, ai_addr 및 ai_next 멤버는 0 또는 NULL이어야 합니다. 그렇지 않으면 GetAddrInfoEx 함수가 WSANO_RECOVERY 실패합니다.

자세한 내용은 설명을 참조하세요.

[out] ppResult

호스트에 대한 응답 정보를 포함하는 하나 이상의 addrinfo 구조체의 연결된 목록에 대한 포인터입니다.

반환 값

Success는 0을 반환합니다. 오류는 Windows 소켓 오류 코드에 있는 것처럼 0이 아닌 Windows 소켓 오류 코드를 반환합니다.

getaddrinfo 함수에서 반환되는 대부분의 0이 아닌 오류 코드는 IETF(Internet Engineering Task Force) 권장 사항에 설명된 오류 집합에 매핑됩니다. 다음 표에는 이러한 오류 코드와 해당 WSA에 해당하는 코드가 나와 있습니다. Winsock 프로그래머에게 친숙하고 포괄적인 오류 정보를 제공하므로 WSA 오류 코드를 사용하는 것이 좋습니다.

오류 값 WSA 등가 Description
EAI_AGAIN WSATRY_AGAIN 이름 확인에 일시적인 오류가 발생했습니다.
EAI_BADFLAGS WSAEINVAL pHints 매개 변수의 ai_flags 멤버에 대해 잘못된 값이 제공되었습니다.
EAI_FAIL WSANO_RECOVERY 이름 확인에서 복구할 수 없는 오류가 발생했습니다.
EAI_FAMILY WSAEAFNOSUPPORT pHints 매개 변수의 ai_family 멤버는 지원되지 않습니다.
EAI_MEMORY WSA_NOT_ENOUGH_MEMORY 메모리 할당 오류가 발생했습니다.
EAI_NONAME WSAHOST_NOT_FOUND 제공된 매개 변수에 대한 이름이 resolve 않거나 pNodeNamepServiceName 매개 변수가 제공되지 않았습니다.
EAI_SERVICE WSATYPE_NOT_FOUND pServiceName 매개 변수는 pHints 매개 변수의 지정된 ai_socktype 멤버에 대해 지원되지 않습니다.
EAI_SOCKTYPE WSAESOCKTNOSUPPORT pHints 매개 변수의 ai_socktype 멤버는 지원되지 않습니다.
 

gai_strerror 함수를 사용하여 getaddrinfo 함수에서 반환된 EAI 코드를 기반으로 오류 메시지를 출력합니다. gai_strerror 함수는 IETF 권장 사항을 준수하기 위해 제공되지만 스레드로부터 안전하지는 않습니다. 따라서 WSAGetLastError 와 같은 기존 Windows 소켓 함수를 사용하는 것이 좋습니다.

오류 코드 의미
WSA_NOT_ENOUGH_MEMORY
작업을 수행할 메모리가 부족했습니다.
WSAEAFNOSUPPORT
요청한 프로토콜과 호환되지 않는 주소가 사용되었습니다. 이 오류는 pHints 매개 변수가 가리키는 addrinfo 구조체의 ai_family 멤버가 지원되지 않는 경우 반환됩니다.
WSAEINVAL
잘못된 인수가 지정되었습니다. pHints 매개 변수가 가리키는 addrinfo 구조체의 ai_flags 멤버에 대해 잘못된 값이 제공된 경우 이 오류가 반환됩니다.
WSAESOCKTNOSUPPORT
이 주소 패밀리에서는 지정된 소켓 형식이 지원되지 않습니다. pHints 매개 변수가 가리키는 addrinfo 구조체의 ai_socktype 멤버가 지원되지 않으면 이 오류가 반환됩니다.
WSAHOST_NOT_FOUND
호스트를 확인할 수 없습니다. 이 오류는 제공된 매개 변수에 대한 이름이 resolve 않거나 pNodeNamepServiceName 매개 변수가 제공되지 않은 경우 반환됩니다.
WSANO_DATA
요청한 이름은 유효하지만 요청한 형식의 데이터를 찾을 수 없습니다.
WSANO_RECOVERY
데이터베이스 조회 중에 복구할 수 없는 오류가 발생했습니다. 이름 확인에서 복구할 수 없는 오류가 발생한 경우 이 오류가 반환됩니다.
WSANOTINITIALISED
이 함수를 사용하기 전에 성공적인 WSAStartup 호출이 발생해야 합니다.
WSATRY_AGAIN
로컬 서버가 해당 서버로부터 응답을 받지 못해 발생한 일시적인 오류입니다. 이 오류는 이름 확인에서 일시적인 오류가 발생했을 때 반환됩니다.
WSATYPE_NOT_FOUND
지정된 클래스를 찾을 수 없습니다. pServiceName 매개 변수는 pHints 매개 변수가 가리키는 addrinfo 구조체의 지정된 ai_socktype 멤버에 대해 지원되지 않습니다.

설명

getaddrinfo 함수는 호스트 이름에서 주소로 프로토콜 독립적 변환을 제공하는 함수의 ANSI 버전입니다. 이 함수의 유니코드 버전은 GetAddrInfoW입니다. 개발자는 getaddrinfo ANSI 함수 대신 GetAddrInfoW 유니코드 함수를 사용하는 것이 좋습니다.

getaddrinfo 함수는 NS_DNS 네임스페이스에 대한 결과를 반환합니다. 두 개 이상의 네임스페이스 공급자가 정보를 반환하는 경우 getaddrinfo 함수는 모든 응답을 집계합니다. IPv6 및 IPv4 프로토콜과 함께 사용할 경우 이름 확인은 DNS(Domain Name System), 로컬 호스트 파일 또는 NS_DNS 네임스페이스에 대한 다른 명명 메커니즘을 통해 확인할 수 있습니다.

getaddrinfo 함수에 사용할 수 있는 또 다른 이름은 GetAddrInfoA입니다. Ws2tcpip.h 헤더 파일의 매크로는 GetAddrInfoAgetaddrinfo로 정의합니다.

Ws2tcpip.h 헤더 파일의 매크로는 GetAddrInfo의 혼합 대/소문자 함수 이름과 ADDRINFOT 구조를 정의합니다. 이 GetAddrInfo 함수는 TCHAR 형식의 포인터의 pNodeNamepServiceName 매개 변수와 ADDRINFOT 형식의 포인터에 대한 pHintsppResult 매개 변수를 사용하여 호출해야 합니다. UNICODE 또는 _UNICODE 정의되지 않은 경우 GetAddrInfo 는 함수의 ANSI 버전인 getaddrinfo로 정의되고 ADDRINFOTaddrinfo 구조에 정의됩니다. UNICODE 또는 _UNICODE 정의되면 GetAddrInfo는 함수의 유니코드 버전인 GetAddrInfoW로 정의되고 ADDRINFOTaddrinfoW 구조에 정의됩니다.

Windows Server 2003용 SDK(플랫폼 소프트웨어 개발 키트)의 Ws2tcpip.h 헤더 파일에 정의된 getaddrinfo 함수의 매개 변수 이름 및 매개 변수 형식과 Windows XP는 달랐습니다.

pNodeName 또는 pServiceName 매개 변수 중 하나 또는 둘 다 NULL로 종료된 ANSI 문자열을 가리킵니다. 일반적으로 둘 다 제공됩니다.

성공하면 연결된 addrinfo 구조 목록이 ppResult 매개 변수에 반환됩니다. NULL 포인터가 발생할 때까지 반환된 각 addrinfo 구조의 ai_next 멤버에 제공된 포인터를 따라 목록을 처리할 수 있습니다. 반환된 각 addrinfo 구조에서 ai_family, ai_socktypeai_protocol 멤버는 소켓 또는 WSASocket 함수 호출의 각 인수에 해당합니다. 또한 반환된 각 addrinfo 구조체의 ai_addr 멤버는 채워진 소켓 주소 구조를 가리키며, 길이는 ai_addrlen 멤버에 지정됩니다.

pNodeName 매개 변수가 컴퓨터 이름을 가리키는 경우 원본 주소로 사용할 수 있는 컴퓨터의 모든 영구 주소가 반환됩니다. Windows Vista 이상에서 이러한 주소에는 MIB_UNICASTIPADDRESS_ROW 구조에서SkipAsSource 멤버가 false로 설정된 GetUnicastIpAddressTable 또는 GetUnicastIpAddressEntry 함수에서 반환된 모든 유니캐스트 IP 주소가 포함됩니다.

pNodeName 매개 변수가 "localhost"와 같은 문자열을 가리키는 경우 로컬 컴퓨터의 모든 루프백 주소가 반환됩니다.

pNodeName 매개 변수에 빈 문자열이 포함된 경우 로컬 컴퓨터의 등록된 모든 주소가 반환됩니다.

Windows Server 2003 이상에서 pNodeName 매개 변수가 ".와 같은 문자열을 가리키는 경우. localmachine", 로컬 컴퓨터에 등록된 모든 주소가 반환됩니다.

pNodeName 매개 변수가 클러스터 가상 서버 이름을 참조하는 경우 가상 서버 주소만 반환됩니다. Windows Vista 이상에서 이러한 주소에는 MIB_UNICASTIPADDRESS_ROW 구조에서SkipAsSource 멤버가 true로 설정된 GetUnicastIpAddressTable 또는 GetUnicastIpAddressEntry 함수에서 반환된 모든 유니캐스트 IP 주소가 포함됩니다. 클러스터링 대한 자세한 내용은 Windows 클러스터링을 참조하세요.

WINDOWS 7 sp1(서비스 팩 1) 및 Windows Server 2008 R2 SP1(서비스 팩 1)은 IP 주소에서 SkipAsSource 특성을 설정하기 위한 Netsh.exe 지원을 추가합니다. 또한 MIB_UNICASTIPADDRESS_ROW 구조의 SkipAsSource 멤버가 false로 설정된 경우 IP 주소가 DNS에 등록되도록 동작이 변경됩니다. SkipAsSource 멤버가 true로 설정된 경우 IP 주소가 DNS에 등록되지 않습니다.

IP 주소에서 SkipAsSource 특성을 설정하기 위한 Netsh.exe 지원을 추가하는 Windows 7 및 Windows Server 2008 R2에 핫픽스를 사용할 수 있습니다. 또한 이 핫픽스는 MIB_UNICASTIPADDRESS_ROW 구조의 SkipAsSource 멤버가 false로 설정된 경우 IP 주소가 DNS에 등록되도록 동작을 변경합니다. SkipAsSource 멤버가 true로 설정된 경우 IP 주소가 DNS에 등록되지 않습니다. 자세한 내용은 기술 자료(KB) 2386184.

IP 주소에서 SkipAsSource 특성을 설정하기 위한 Netsh.exe 지원을 추가하는 WINDOWS Vista SP2(서비스 팩 2) 및 Windows Server 2008 SP2(서비스 팩 2)에서도 비슷한 핫픽스를 사용할 수 있습니다. 또한 이 핫픽스는 MIB_UNICASTIPADDRESS_ROW 구조의 SkipAsSource 멤버가 false로 설정된 경우 IP 주소가 DNS에 등록되도록 동작을 변경합니다. SkipAsSource 멤버가 true로 설정된 경우 IP 주소가 DNS에 등록되지 않습니다.

getaddrinfo 함수의 호출자는 pHints 매개 변수가 가리키는 addrinfo 구조를 통해 지원되는 소켓 유형에 대한 힌트를 제공할 수 있습니다. pHints 매개 변수를 사용하는 경우 연결된 addrinfo 구조에 다음 규칙이 적용됩니다.

  • ai_family AF_UNSPEC 값은 호출자가 AF_INETAF_INET6 주소 패밀리만 수락했음을 나타냅니다. AF_UNSPECPF_UNSPEC 동일합니다.
  • ai_socktype 값은 호출자가 소켓 형식을 수락했음을 나타냅니다.
  • ai_protocol 값은 호출자가 모든 프로토콜을 수락했음을 나타냅니다.
  • ai_addrlen 멤버를 0으로 설정해야 합니다.
  • ai_canonname 멤버를 NULL로 설정해야 합니다.
  • ai_addr 멤버를 NULL로 설정해야 합니다.
  • ai_next 멤버를 NULL로 설정해야 합니다.

ai_family 대한 AF_UNSPEC 값은 호출자가 프로토콜 패밀리를 수락했음을 나타냅니다. 이 값은 pNodeName 매개 변수가 가리키는 호스트 이름에 대한 IPv4 및 IPv6 주소를 모두 반환하는 데 사용할 수 있습니다. Windows Server 2003 및 Windows XP에서 IPv6 주소는 IPv6이 로컬 컴퓨터에 설치된 경우에만 반환됩니다.

pHints 매개 변수에 제공된 addrinfo 구조의 다른 값은 특정 요구 사항을 나타냅니다. 예를 들어 호출자가 IPv4만 처리하고 IPv6을 처리하지 않는 경우 ai_family 멤버를 AF_INET 설정해야 합니다. 또 다른 예로, 호출자가 TCP만 처리하고 UDP를 처리하지 않는 경우 ai_socktype 멤버를 SOCK_STREAM 설정해야 합니다.

pHints 매개 변수가 NULL 포인터인 경우 getaddrinfo 함수는 pHintsaddrinfo 구조체가 AF_UNSPEC 로 설정된 ai_family멤버로 초기화된 것처럼 처리하고 다른 모든 멤버는 0으로 설정합니다.

Windows Vista 이상에서 getaddrinfo 가 서비스에서 호출되는 경우 작업이 서비스를 호출하는 사용자 프로세스의 결과인 경우 서비스는 사용자를 가장해야 합니다. 이는 보안을 올바르게 적용할 수 있도록 하기 위한 것입니다.

getaddrinfo 함수를 사용하여 IP 주소의 텍스트 문자열 표현을 IP 주소 및 기타 정보에 대한 sockaddr 구조가 포함된 addrinfo 구조로 변환할 수 있습니다. 이러한 방식으로 사용하려면 pNodeName 매개 변수가 가리키는 문자열에 IP 주소의 텍스트 표현이 포함되어야 하며 pHints 매개 변수가 가리키는 addrinfo 구조에는 ai_flags 멤버에 설정된 AI_NUMERICHOST 플래그가 있어야 합니다. pNodeName 매개 변수가 가리키는 문자열에는 IPv4 또는 IPv6 주소의 텍스트 표현이 포함될 수 있습니다. 텍스트 IP 주소는 ppResult 매개 변수가 가리키는 addrinfo 구조로 변환됩니다. 반환된 addrinfo 구조체에는 IP 주소에 대한 추가 정보와 함께 IP 주소에 대한 sockaddr 구조가 포함됩니다. 이 메서드가 Windows Server 2003 및 Windows XP에서 IPv6 주소 문자열로 작동하려면 로컬 컴퓨터에 IPv6 프로토콜을 설치해야 합니다. 그렇지 않으면 WSAHOST_NOT_FOUND 오류가 반환됩니다.

동적 할당에서 주소 정보 해제

ppResult 매개 변수가 가리키는 getaddrinfo 함수에서 반환하는 모든 정보는 addrinfo 구조체, 소켓 주소 구조 및 addrinfo 구조체가 가리키는 정식 호스트 이름 문자열을 포함하여 동적으로 할당됩니다. 이 함수를 성공적으로 호출하여 할당된 메모리는 freeaddrinfo에 대한 후속 호출과 함께 해제되어야 합니다.

예제 코드

다음 코드 예제에서는 getaddrinfo 함수를 사용하는 방법을 보여줍니다.
#undef UNICODE

#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;
    int iResult;
    INT iRetval;

    DWORD dwRetval;

    int i = 1;
    
    struct addrinfo *result = NULL;
    struct addrinfo *ptr = NULL;
    struct addrinfo hints;

    struct sockaddr_in  *sockaddr_ipv4;
//    struct sockaddr_in6 *sockaddr_ipv6;
    LPSOCKADDR sockaddr_ip;

    char ipstringbuffer[46];
    DWORD ipbufferlength = 46;

    // Validate the parameters
    if (argc != 3) {
        printf("usage: %s <hostname> <servicename>\n", argv[0]);
        printf("getaddrinfo provides protocol-independent translation\n");
        printf("   from an ANSI host name to an IP address\n");
        printf("%s example usage\n", argv[0]);
        printf("   %s www.contoso.com 0\n", argv[0]);
        return 1;
    }

    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0) {
        printf("WSAStartup failed: %d\n", iResult);
        return 1;
    }

    //--------------------------------
    // Setup the hints address info structure
    // which is passed to the getaddrinfo() function
    ZeroMemory( &hints, sizeof(hints) );
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    printf("Calling getaddrinfo with following parameters:\n");
    printf("\tnodename = %s\n", argv[1]);
    printf("\tservname (or port) = %s\n\n", argv[2]);
    
//--------------------------------
// Call getaddrinfo(). If the call succeeds,
// the result variable will hold a linked list
// of addrinfo structures containing response
// information
    dwRetval = getaddrinfo(argv[1], argv[2], &hints, &result);
    if ( dwRetval != 0 ) {
        printf("getaddrinfo failed with error: %d\n", dwRetval);
        WSACleanup();
        return 1;
    }

    printf("getaddrinfo returned success\n");
    
    // Retrieve each address and print out the hex bytes
    for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {

        printf("getaddrinfo response %d\n", i++);
        printf("\tFlags: 0x%x\n", ptr->ai_flags);
        printf("\tFamily: ");
        switch (ptr->ai_family) {
            case AF_UNSPEC:
                printf("Unspecified\n");
                break;
            case AF_INET:
                printf("AF_INET (IPv4)\n");
                sockaddr_ipv4 = (struct sockaddr_in *) ptr->ai_addr;
                printf("\tIPv4 address %s\n",
                    inet_ntoa(sockaddr_ipv4->sin_addr) );
                break;
            case AF_INET6:
                printf("AF_INET6 (IPv6)\n");
                // the InetNtop function is available on Windows Vista and later
                // sockaddr_ipv6 = (struct sockaddr_in6 *) ptr->ai_addr;
                // printf("\tIPv6 address %s\n",
                //    InetNtop(AF_INET6, &sockaddr_ipv6->sin6_addr, ipstringbuffer, 46) );
                
                // We use WSAAddressToString since it is supported on Windows XP and later
                sockaddr_ip = (LPSOCKADDR) ptr->ai_addr;
                // The buffer length is changed by each call to WSAAddresstoString
                // So we need to set it for each iteration through the loop for safety
                ipbufferlength = 46;
                iRetval = WSAAddressToString(sockaddr_ip, (DWORD) ptr->ai_addrlen, NULL, 
                    ipstringbuffer, &ipbufferlength );
                if (iRetval)
                    printf("WSAAddressToString failed with %u\n", WSAGetLastError() );
                else    
                    printf("\tIPv6 address %s\n", ipstringbuffer);
                break;
            case AF_NETBIOS:
                printf("AF_NETBIOS (NetBIOS)\n");
                break;
            default:
                printf("Other %ld\n", ptr->ai_family);
                break;
        }
        printf("\tSocket type: ");
        switch (ptr->ai_socktype) {
            case 0:
                printf("Unspecified\n");
                break;
            case SOCK_STREAM:
                printf("SOCK_STREAM (stream)\n");
                break;
            case SOCK_DGRAM:
                printf("SOCK_DGRAM (datagram) \n");
                break;
            case SOCK_RAW:
                printf("SOCK_RAW (raw) \n");
                break;
            case SOCK_RDM:
                printf("SOCK_RDM (reliable message datagram)\n");
                break;
            case SOCK_SEQPACKET:
                printf("SOCK_SEQPACKET (pseudo-stream packet)\n");
                break;
            default:
                printf("Other %ld\n", ptr->ai_socktype);
                break;
        }
        printf("\tProtocol: ");
        switch (ptr->ai_protocol) {
            case 0:
                printf("Unspecified\n");
                break;
            case IPPROTO_TCP:
                printf("IPPROTO_TCP (TCP)\n");
                break;
            case IPPROTO_UDP:
                printf("IPPROTO_UDP (UDP) \n");
                break;
            default:
                printf("Other %ld\n", ptr->ai_protocol);
                break;
        }
        printf("\tLength of this sockaddr: %d\n", ptr->ai_addrlen);
        printf("\tCanonical name: %s\n", ptr->ai_canonname);
    }

    freeaddrinfo(result);
    WSACleanup();

    return 0;
}

참고 개발 환경이 각각 addrinfogetaddrinfo에 대한 구조 및 함수 정의를 포함하는 최신 버전의 Ws2tcpip.h를 대상으로 지정하는지 확인합니다.
 

국제화된 도메인 이름

인터넷 호스트 이름은 일반적으로 매우 제한된 문자 집합으로 구성됩니다.
  • 영문자의 대문자 및 소문자 ASCII 문자.
  • 0~9의 숫자.
  • ASCII 하이픈 문자입니다.

인터넷이 증가함에 따라 ASCII 문자 집합으로 표현되지 않는 다른 언어의 인터넷 호스트 이름을 식별해야 할 필요성이 커지고 있습니다. 이러한 요구 사항을 용이하게 하고 비 ASCII 문자(유니코드)를 특수 ASCII 문자 문자열로 나타낼 수 있도록 하는 식별자를 IDN(Internationalized Domain Names)으로 알려져 있습니다. IDNA(애플리케이션에서 도메인 이름 국제화)라는 메커니즘은 표준 방식으로 IDN을 처리하는 데 사용됩니다. IDN 및 IDNA 사양은 IETF(인터넷 엔지니어링 태스크 포스)에서 게시한 RFC 3490, RTF 5890RFC 6365 에 설명되어 있습니다.

Windows 8 및 Windows Server 2012 getaddrinfo 함수는 pNodeName 매개 변수에 전달된 이름에 적용되는 IDN(Internationalized Domain Name) 구문 분석에 대한 지원을 제공합니다. Winsock은 Punycode/IDN 인코딩 및 변환을 수행합니다. 이 동작은 아래에 설명된 AI_DISABLE_IDN_ENCODING 플래그를 사용하여 사용하지 않도록 설정할 수 있습니다.

Windows 7 및 Windows Server 2008 R2 이하에서 getaddrinfo 함수는 현재 pNodeName 매개 변수에 전달된 이름에 적용된 지원 IDN 구문 분석을 제공하지 않습니다. Winsock은 Punycode/IDN 변환을 수행하지 않습니다. GetAddrInfo 함수의 와이드 문자 버전은 RFC 3490에 따라 IDN을 변환하는 데 Punycode를 사용하지 않습니다. DNS를 쿼리할 때 GetAddrInfo 함수의 와이드 문자 버전은 엔터프라이즈 환경의 Microsoft DNS 서버에서 사용하는 형식인 UTF-8 형식으로 유니코드 이름을 인코딩합니다.

Windows Vista 이상의 여러 함수는 IDN의 유니코드 레이블 간 변환을 ASCII에 해당하는 함수로 지원합니다. 각 유니코드 레이블의 결과 표현은 ASCII 문자만 포함하며 유니코드 레이블에 ASCII가 아닌 문자가 포함된 경우 xn-- 접두사로 시작합니다. 일부 DNS 도구 및 서버는 ASCII 문자만 지원하므로 인터넷의 기존 DNS 서버를 지원하기 때문입니다( RFC 3490 참조).

IdnToAscii 함수는 PUNycode를 사용하여 RFC 3490에 정의된 표준 알고리즘을 사용하여 IDN을 원래 유니코드 문자열의 ASCII 표현으로 변환합니다. IdnToUnicode 함수는 IDN의 ASCII 형식을 일반 유니코드 UTF-16 인코딩 구문으로 변환합니다. 관련 초안 표준에 대한 자세한 내용 및 링크는 IDN(Internationalized Domain Names) 처리를 참조하세요.

IdnToAscii 함수를 사용하여 IDN 이름을 ASCII 형식으로 변환한 다음, pNodeName 매개 변수에서 getaddrinfo 함수로 전달할 수 있습니다. 이 함수의 와이드 문자 버전이 사용될 때(UNICODE 또는 _UNICODE 정의된 경우) 이 IDN 이름을 GetAddrInfo 함수에 전달하려면 MultiByteToWideChar 함수를 사용하여 CHAR 문자열을 WCHAR 문자열로 변환할 수 있습니다.

pHints 매개 변수에서 ai_flags 사용

pHints 매개 변수에 제공된 선택적 addrinfo 구조체의 ai_flags 멤버에 있는 플래그는 함수의 동작을 수정합니다.

이러한 플래그 비트는 Windows 7용 Microsoft SDK(Windows SDK(소프트웨어 개발 키트))의 Ws2def.h 헤더 파일에 정의되어 있습니다. 이러한 플래그 비트는 Windows Server 2008 및 Windows Vista용 Windows SDK Ws2tcpip.h 헤더 파일에 정의되어 있습니다. 이러한 플래그 비트는 Windows Server 2003 및 Windows XP용 플랫폼 SDK의 Ws2tcpip.h 헤더 파일에 정의되어 있습니다.

플래그 비트는 다음의 조합일 수 있습니다.

플래그 비트 Description
AI_PASSIVE AI_PASSIVE 플래그를 설정하면 호출자가 바인딩 함수에 대한 호출에서 반환된 소켓 주소 구조를 사용하려고 했음을 나타냅니다. AI_PASSIVE 플래그가 설정되고 pNodeNameNULL 포인터인 경우 소켓 주소 구조의 IP 주소 부분은 IPv4 주소에 대해 INADDR_ANY, IPv6 주소의 경우 IN6ADDR_ANY_INIT 설정됩니다.

AI_PASSIVE 플래그가 설정되지 않은 경우 반환된 소켓 주소 구조는 연결 지향 프로토콜에 대한 connect 함수를 호출하거나 연결 없는 프로토콜에 대한 connect, sendto 또는 send 함수를 호출할 준비가 됩니다. 이 경우 pNodeName 매개 변수가 NULL 포인터인 경우 소켓 주소 구조의 IP 주소 부분은 루프백 주소로 설정됩니다.

AI_CANONNAME AI_CANONNAME 또는 AI_NUMERICHOST 모두 사용되지 않으면 getaddrinfo 함수는 확인을 시도합니다. 리터럴 문자열이 전달되면 getaddrinfo는 문자열을 변환하려고 시도하고 호스트 이름이 전달되면 getaddrinfo 함수는 이름을 주소 또는 여러 주소로 resolve 시도합니다.

AI_CANONNAME 비트가 설정되면 pNodeName 매개 변수는 NULL일 수 없습니다. 그렇지 않으면 getaddrinfo 함수가 WSANO_RECOVERY 함께 실패합니다.

AI_CANONNAME 비트가 설정되고 getaddrinfo 함수가 성공을 반환하면 ppResult 매개 변수의 ai_canonname 멤버가 지정된 노드의 정식 이름을 포함하는 NULL로 끝나는 문자열을 가리킵니다.

참고getaddrinfo 함수는 AI_CANONNAME 플래그가 설정된 경우 성공을 반환할 수 있지만 연결된 addrinfo 구조체의 ai_canonname 멤버는 NULL입니다. 따라서 AI_CANONNAME 플래그를 사용하는 것이 좋습니다. 여기에는 연결된 addrinfo 구조의 ai_canonname 멤버가 NULL인지 여부를 테스트하는 것이 포함됩니다.
 
AI_NUMERICHOST AI_NUMERICHOST 비트가 설정되면 pNodeName 매개 변수에 NULL이 아닌 숫자 호스트 주소 문자열이 포함되어야 합니다. 그렇지 않으면 EAI_NONAME 오류가 반환됩니다. 이 플래그는 이름 확인 서비스가 호출되지 않도록 합니다.
AI_NUMERICSERV AI_NUMERICSERV 비트가 설정되면 pServiceName 매개 변수에 NULL이 아닌 숫자 포트 번호가 포함되어야 합니다. 그렇지 않으면 EAI_NONAME 오류가 반환됩니다. 이 플래그를 사용하면 이름 확인 서비스가 호출되지 않습니다.

AI_NUMERICSERV 플래그는 Windows Vista 이상용 Windows SDK 정의됩니다. AI_NUMERICSERV 플래그는 Microsoft 공급자에서 지원되지 않습니다.

AI_ALL AI_ALL 비트가 설정되면 AI_V4MAPPED 있는 IPv6 주소 및 IPv4 주소에 대한 요청이 이루어집니다.

AI_ALL 플래그는 Windows Vista용 Windows SDK 이상에서 정의됩니다. AI_ALL 플래그는 Windows Vista 이상에서 지원됩니다.

AI_ADDRCONFIG AI_ADDRCONFIG 비트가 설정된 경우 전역 주소가 구성된 경우에만 getaddrinfo가 resolve. AI_ADDRCONFIG 플래그를 지정하는 경우 IPv4 주소는 로컬 시스템에 IPv4 주소가 구성된 경우에만 반환되고 IPv6 주소는 로컬 시스템에 구성된 경우에만 반환됩니다. IPv4 또는 IPv6 루프백 주소는 유효한 전역 주소로 간주되지 않습니다.

AI_ADDRCONFIG 플래그는 Windows Vista용 Windows SDK 이상에서 정의됩니다. AI_ADDRCONFIG 플래그는 Windows Vista 이상에서 지원됩니다.

AI_V4MAPPED AI_V4MAPPED 비트가 설정되고 IPv6 주소에 대한 요청이 실패하면 IPv4 주소에 대한 이름 서비스 요청이 이루어지고 이러한 주소는 IPv4 매핑된 IPv6 주소 형식으로 변환됩니다.

AI_V4MAPPED 플래그는 Windows Vista용 Windows SDK 이상에서 정의됩니다. AI_V4MAPPED 플래그는 Windows Vista 이상에서 지원됩니다.

AI_NON_AUTHORITATIVE AI_NON_AUTHORITATIVE 비트가 설정되면 NS_EMAIL 네임스페이스 공급자는 신뢰할 수 있는 결과와 신뢰할 수 없는 결과를 모두 반환합니다. AI_NON_AUTHORITATIVE 비트가 설정되지 않은 경우 NS_EMAIL 네임스페이스 공급자는 신뢰할 수 있는 결과만 반환합니다.

AI_NON_AUTHORITATIVE 플래그는 Windows Vista용 Windows SDK 이상에서 정의됩니다. AI_NON_AUTHORITATIVE 플래그는 Windows Vista 이상에서 지원되며 NS_EMAIL 네임스페이스에만 적용됩니다.

AI_SECURE AI_SECURE 비트가 설정된 경우 NS_EMAIL 네임스페이스 공급자는 보안 강화를 통해 얻은 결과를 반환하여 스푸핑 가능성을 최소화합니다.

AI_SECURE 플래그는 Windows Vista용 Windows SDK 이상에서 정의됩니다. AI_SECURE 플래그는 Windows Vista 이상에서 지원되며 NS_EMAIL 네임스페이스에만 적용됩니다.

AI_RETURN_PREFERRED_NAMES AI_RETURN_PREFERRED_NAMES 설정된 경우 pNodeName 매개 변수에 이름을 입력하지 않아야 합니다. NS_EMAIL 네임스페이스 공급자는 게시에 대한 기본 이름을 반환합니다.

AI_RETURN_PREFERRED_NAMES 플래그는 Windows Vista 이상용 Windows SDK 정의됩니다. AI_RETURN_PREFERRED_NAMES 플래그는 Windows Vista 이상에서 지원되며 NS_EMAIL 네임스페이스에만 적용됩니다.

AI_FQDN AI_FQDN 설정되고 플랫 이름(단일 레이블)을 지정하면 getaddrinfo는 이름이 최종적으로 확인된 정규화된 도메인 이름을 반환합니다. 정규화된 도메인 이름은 연결된 addrinfo 구조의 ai_canonname 멤버에 반환됩니다. 이는 DNS에 등록된 정식 이름을 반환하는 AI_CANONNAME 비트 플래그와 다르며, 이는 플랫 이름이 확인된 정규화된 도메인 이름과 다를 수 있습니다. AI_FQDNAI_CANONNAME 비트 중 하나만 설정할 수 있습니다. 두 플래그가 모두 EAI_BADFLAGS 있으면 getaddrinfo 함수가 실패합니다.

AI_FQDN 비트가 설정되면 pNodeName 매개 변수는 NULL일 수 없습니다. 그렇지 않으면 GetAddrInfoEx 함수가 WSANO_RECOVERY 실패합니다.

Windows 7: AI_FQDN 플래그는 Windows 7 이상용 Windows SDK 정의됩니다. AI_FQDN 플래그는 Windows 7 이상에서 지원됩니다.

AI_FILESERVER AI_FILESERVER 설정된 경우 쿼리 중인 호스트 이름이 파일 공유 시나리오에서 사용되고 있음을 네임스페이스 공급자에 대한 힌트입니다. 네임스페이스 공급자는 이 힌트를 무시할 수 있습니다.

Windows 7: AI_FILESERVER 플래그는 Windows 7 이상용 Windows SDK 정의됩니다. AI_FILESERVER 플래그는 Windows 7 이상에서 지원됩니다.

 

AI_NUMERICHOST 사용하는 예제 코드

다음 코드 예제에서는 getaddrinfo 함수를 사용하여 IP 주소의 텍스트 문자열 표현을 IP 주소 및 기타 정보에 대한 sockaddr 구조가 포함된 addrinfo 구조체로 변환하는 방법을 보여 줍니다.
#undef UNICODE

#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;
    int iResult;

    DWORD dwRetval;

    int i = 1;
    
    struct addrinfo *result = NULL;
    struct addrinfo *ptr = NULL;
    struct addrinfo hints;


    // Validate the parameters
    if (argc != 2) {
        printf("usage: %s <IP Address String>\n", argv[0]);
        printf("  getaddrinfo determines the IP binary network address\n");
        printf("       %s 207.46.197.32\n", argv[0]);  /* www.contoso.com */
        return 1;
    }
    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0) {
        printf("WSAStartup failed: %d\n", iResult);
        return 1;
    }

    //--------------------------------
    // Setup the hints address info structure
    // which is passed to the getaddrinfo() function
    ZeroMemory( &hints, sizeof(hints) );
    hints.ai_flags = AI_NUMERICHOST;
    hints.ai_family = AF_UNSPEC;
//    hints.ai_socktype = SOCK_STREAM;
//    hints.ai_protocol = IPPROTO_TCP;


//--------------------------------
// Call getaddrinfo(). If the call succeeds,
// the result variable will hold a linked list
// of addrinfo structures containing response
// information
    dwRetval = getaddrinfo(argv[1], NULL, &hints, &result);
    if ( dwRetval != 0 ) {
        printf("getaddrinfo failed with error: %d\n", dwRetval);
        WSACleanup();
        return 1;
    }

    printf("getaddrinfo returned success\n");
    
    // Retrieve each address and print out the hex bytes
    for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {

        printf("getaddrinfo response %d\n", i++);
        printf("\tFlags: 0x%x\n", ptr->ai_flags);
        printf("\tFamily: ");
        switch (ptr->ai_family) {
            case AF_UNSPEC:
                printf("Unspecified\n");
                break;
            case AF_INET:
                printf("AF_INET (IPv4)\n");
                break;
            case AF_INET6:
                printf("AF_INET6 (IPv6)\n");
                break;
            case AF_NETBIOS:
                printf("AF_NETBIOS (NetBIOS)\n");
                break;
            default:
                printf("Other %ld\n", ptr->ai_family);
                break;
        }
        printf("\tSocket type: ");
        switch (ptr->ai_socktype) {
            case 0:
                printf("Unspecified\n");
                break;
            case SOCK_STREAM:
                printf("SOCK_STREAM (stream)\n");
                break;
            case SOCK_DGRAM:
                printf("SOCK_DGRAM (datagram) \n");
                break;
            case SOCK_RAW:
                printf("SOCK_RAW (raw) \n");
                break;
            case SOCK_RDM:
                printf("SOCK_RDM (reliable message datagram)\n");
                break;
            case SOCK_SEQPACKET:
                printf("SOCK_SEQPACKET (pseudo-stream packet)\n");
                break;
            default:
                printf("Other %ld\n", ptr->ai_socktype);
                break;
        }
        printf("\tProtocol: ");
        switch (ptr->ai_protocol) {
            case 0:
                printf("Unspecified\n");
                break;
            case IPPROTO_TCP:
                printf("IPPROTO_TCP (TCP)\n");
                break;
            case IPPROTO_UDP:
                printf("IPPROTO_UDP (UDP) \n");
                break;
            default:
                printf("Other %ld\n", ptr->ai_protocol);
                break;
        }
        printf("\tLength of this sockaddr: %d\n", ptr->ai_addrlen);
        printf("\tCanonical name: %s\n", ptr->ai_canonname);
    }

    freeaddrinfo(result);
    WSACleanup();

    return 0;
}

Windows 2000 및 이전 버전에서 getaddrinfo 지원

getaddrinfo 함수가 Windows XP 이상에서 Ws2_32.dll 추가되었습니다. 이전 버전의 Windows에서 이 함수를 사용하는 애플리케이션을 실행하려면 Ws2tcpip.hWspiapi.h 파일을 포함해야 합니다. Wspiapi.h include 파일이 추가되면 getaddrinfo 함수는 Wspiapi.h 파일의 WspiapiGetAddrInfo 인라인 함수에 정의됩니다. 런타임에 WspiapiGetAddrInfo 함수는 Ws2_32.dll 또는 Wship6.dll(Windows 2000용 IPv6 기술 미리 보기의 getaddrinfo 가 포함된 파일)에 getaddrinfo가 포함되지 않은 경우 Wspiapi.h 헤더 파일의 코드를 기반으로 getaddrinfo 버전이 인라인으로 구현되는 방식으로 구현됩니다. 이 인라인 코드는 getaddrinfo 함수를 기본적으로 지원하지 않는 이전 Windows 플랫폼에서 사용됩니다.

IPv6 프로토콜은 Windows 2000용 IPv6 기술 미리 보기가 설치된 경우 Windows 2000에서 지원됩니다. 그렇지 않으면 Windows XP 이전 버전의 Windows에서 getaddrinfo 지원이 IPv4 이름 확인을 처리하는 것으로 제한됩니다.

GetAddrInfoW 함수는 getaddrinfo의 유니코드 버전입니다. GetAddrInfoW 함수가 WINDOWS XP SP2(서비스 팩 2)의 Ws2_32.dll 추가되었습니다. GetAddrInfoW 함수는 WINDOWS XP SP2 이전 버전의 Windows에서 사용할 수 없습니다.

Windows Phone 8: 이 함수는 Windows Phone 8 이상에서 Windows Phone 스토어 앱에서 지원됩니다.

Windows 8.1Windows Server 2012 R2: 이 함수는 Windows 8.1, Windows Server 2012 R2 이상에서 Windows 스토어 앱에서 지원됩니다.

요구 사항

요구 사항
지원되는 최소 클라이언트 Windows 8.1, Windows Vista [데스크톱 앱 | UWP 앱]
지원되는 최소 서버 Windows Server 2003 [데스크톱 앱 | UWP 앱]
대상 플랫폼 Windows
헤더 ws2tcpip.h
라이브러리 Ws2_32.lib
DLL Ws2_32.dll

추가 정보

GetAddrInfoEx

GetAddrInfoW

IdnToAscii

IdnToUnicode

WSAGetLastError

WSASocket

Winsock 함수

Winsock 참조

addrinfo

addrinfoW

addrinfoex

addrinfoex2

bind

connect

freeaddrinfo

gai_strerror

send

Sendto

socket