domain address를 받아서 네트워크 주소 정보(IP address)를 가져오는 함수
구글이라는 도메인 주소가 있는데, 이 주소는 사람들의 편의를 위해 만든 주소고 컴퓨터는 이 도메인 주소에 대응되는 IP주소를 알아 낸 뒤에 그 IP주소로 연결을 해야한다.
int getaddrinfo(
const char *host,
const char *service,
const struct addrinfo *hints,
struct addrinfo **result
);
void freeaddrinfo(struct addrinfo *result);
getaddrinfo 함수는 총 4개의 매개변수가 있다.
host: 호스트 이름 혹은 주소 문자열(IPv4:xxx.xxx.xxx.xxx)
service: 서비스 이름 호은 10진수로 표현한 포트 번호 문자열
hints: getaddrinfo 함수에 희망하는 유형을 알려준다. addrinfo구조체에 hint로 줄 정보를 채운 뒤, 그것의 주소값을 넘긴다. 이 힌트는 반환받을 result를 제한하는 기준을 정한다.
ex) IPv4주소만 받고 싶거나 IPv6 주소만 받고 싶을 수도 있고, 둘 다 받고 싶을 수도 있는데 이럴 땐 hints의 ai_family의 값을 조작한다.
별도의 hint를 제공하지 않을 경우, NULL을 넣는다.
result: DNS서버로부터 받은 네트워크 주소 정보(IP 주소)를 돌려받는 output 매개변수다. addinfo 구조체를 사용하며, linked list이다. 이 result의 내용중 필요한 것들은 적절히 복사하여 사용자 변수로 옮겨두어야 하며, result는 사용이 끝나는 즉시 freeaddrinfo 함수로 메모리 해제를 해주어야 한다.
함수 에러 시 리턴하는 에러값들은 다양하다.
상세 정보는 다음 블로그에서 - https://techlog.gurucat.net/293
EAI_ADDRFAMILY, EAI_AGAIN, EAI_BADFLAGS, EAI_FAIL, EAI_FAMILY, EAI_MEMORY, EAI_NODATA, EAI_NONAME, EAI_SERVICE, EAI_SOCKET, EAI_SYSTEM 등..
getaddrinfo가 사용하는 addrinfo 구조체 원형
struct addrinfo {
int ai_flags; // 추가적인 옵션을 정의 할 때 사용함. 여러 flag를 bitwise OR-ing 하여 넣는다
int ai_family; // address family를 나타냄. AF_INET, AF_INET6, AF_UNSPEC
int ai_socktype; // socket type을 나타냄. SOCK_SREAM, SOCK_DGRAM
int ai_protocol; // IPv4와 IPv6에 대한 IPPROTO_xxx와 같은 값을 가짐.
socklen_t ai_addrlen; // socket 주소인 ai_addr의 길이를 나타냄
char *ai_canonname; // 호스트의 canonical name을 나타냄
struct sockaddr *ai_addr; // socket 주소를 나타내는 구조체 포인터
struct addrinfo *ai_next; // 주소정보 구조체 addrinfo는 linked list이다. 다음 데이터의 포인터
};
getaddrinfo()에서 hints 인자를 넣을 때, 위의 int형 4개 필드에만(최대 4개) 값을 지정해준다. 나머지는 0(또는 NULL)이어야 한다. 실제 우리는 memset을 활용해서 전체 구조체를 0으로 설정하고, 4개 이하의 필드에만 값을 지정해준다.
ai_flags : 이 필드는 기본 동작을 수정해준다. 여러 예시들을 알아보자.
getnameinfo 함수는 getaddrinfo 함수의 역이다.
이 함수는 소켓 주소 구조체를 대응되는 호스트와 서비스 이름 스트링으로 변환한다.
int getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *service, size_t servlen, int flags);
성공시 0 반환, 실패시 0이 아닌 에러코드 반환
sa: salen 바이트 크기의 소켓 주소 구조체가 들어간다.
host: hostlen 크기의 버퍼, service는 servlen 크기의 버퍼가 들어간다.
함수의 실행이 성공하면 소켓 주소 구조체 sa를 대응되는 호스트와 서비스 이름 스트링으로 변환하고, 이들을 host와 service 버퍼로 복사한다.
호스트 이름을 원하지 않거나 서비스 이름을 원치 않는다면 둘 중 하나는 NULL로 설정이 가능하다.
flags: 비트 마스크로 기본 동작을 수정한다.
flags = NI_NUMERICHOST를 설정한다면 기본값으로 host를 도메인 이름으로 반환하는 것 대신 ip주소 스트링을 대신해서 반환한다.
NI_NUMERICSERV를 설정한다면 서비스 이름 대신 포트 번호를 반환한다.