본문 바로가기

진리는어디에

도메인 이름을 이용해 IP 주소 얻기(getaddrinfo)

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>

int getaddrinfo(const char *node, const char *service,
                const struct addrinfo *hints,
                struct addrinfo **res
);       

struct addrinfo 
{
    int     ai_flags;     /* AI_PASSIVE, AI_CANONNAME */
    int     ai_family;    /* AF_XXX */
    int     ai_socktype;  /* SOCK_XXX */
    int     ai_protocol;  /* 0 or IPPROTO_XXX for IPv4, IPv6 */ 
    size_t  ai_addrlen;   
    struct sockaddr *ai_addr;
    char   *ai_canonname;
    struct addrinfo *ai_next;       
};

DESCRIPTION

일반적으로 hostname이나 ip 또는 서비스 name과 port를 얻어오기 위해 gethostbyname, gethostbyaddr, getservbyname, getservbyport등의 함수를 사용한다. 그중 gethostbyname, gethostbyaddr은 IPv4에서만 사용 될 수 있는 함수고, POSIX에 따르면 언젠가는 퇴출될 함수라고 한다(맞나?) 그래서 여기 새로운 함수가 등장 하는게 그 이름하여 getaddrinfo!!

이 함수의 특징으로는 주소를 짜잘한 문자열이나 기타등등들로 반환하지 않고 struct sockaddr 로 바로 반환하기 때문에 socket function들에서 다이렉트로 불러다 쓸수 있다는 장점이 있고, host name, ip, service name, service port를 함수 하나에서 다 해결 할 수 있다는 강력함이 있다.

ARGUMENTS

    • hostname : hostname이나 ip address 를 적어 준다.
    • service : service name 이나 문자열로 구성된 port number를 적어준다.
    • hint : NULL 포인터이거나 함수 사용자가 리턴받기 원하는 정보 타입을 적어 놓은 addrinfo 구조체를 가리키는 포인터. 예를 들어서 tcp와 udp를 모두 지원하는 서비스가 있고, 그중에 udp 정보에만 관심이 있다면, ai_socktype 멤버를 SOCK_DGRAM으로 셋팅 해 주게되면 result에 udp에 관련된 정보만 리턴된다.

      hint가 NULL로 되어 있을 경우에는 값들을 0으로 간주한다.

      사용자에 의해 정의 될 수 있는 hint의 플래그는 아래와 같다.
      • ai_flags : 0 또는 or 로 연결된 AI_XXX 값들
        AI_PASSIVE : 소켓을 PASSIVE OPEN 모드로 사용한다.
        AI_CANONNAME : (이름이 여러개인 경우)해당 호스트의 대표 이름을 리턴한다.
        ... 그리고 기타등등들...다 적기 힘들다...-_-;
      • ai_family : AF_XXX
      • ai_socktype : SOCK_XXX
      • ai_protocol : IPPROTO_UDP, IPPROTO_TCP
    • result : 결과를 리턴 받을 포인터. 리턴 0이 나오고 함수가 정상적으로 종료 되면, result에는 addrinfo 구조체로 구성된 링크드리스트가 리턴된다(어쩌면 그냥 하나만 리턴 될수도 있다). 

      링크드리스트가 리턴되는 경우는
      • 하나의 호스트 이름에 여러 주소가 붙어 있을 경우, 각 주소마다 하나의 구조체가 리턴된다.
      • 지정된 서비스가 하나 이상의 socket type을 지원 할 경우. 하나의 socket type마다 하나의 구조체가 리턴된다(하지만 만일 hint의 ai_socktype이 지정되어 있다면 이야기가 다르다)

RETURN VALUE

성공시 0 리턴, 실패시 아래의 에러중 하나 리턴

  • EAI_FAMILY :  The requested address family is not supported at all.
  • EAI_SOCKTYPE : The requested socket type is not supported at all.
  • EAI_BADFLAGS : ai_flags contains invalid flags.
  • EAI_NONAME : The node or service is not known.  This error is also returned if both node and service are NULL.
  • EAI_SERVICE : The requested service is not available for the requested socket type.  It may be available through another socket type.

부록 1. 같이 읽으면 좋은 글

유익한 글이었다면 공감(❤) 버튼 꾹!! 추가 문의 사항은 댓글로!!