getaddrinfo()

게임 서버 프로그래밍/윈도우 소켓 프로그래밍

2020. 2. 22. 13:22

※ 작성된 내용은 '멀티플레이 게임 프로그래밍' 책의 내용을 참조하였습니다.

더보기

sockaddr의 초기화 문제

소켓 주소 구조체에 IP 주소나 포트값을 하나씩 채워 넣는 것은 번거로운 작업이다.

특히 프로그램이 설정 파일이나 명령줄에서 문자열을 받아온 경우 더욱 그렇다.

 

윈도에선 InetPton() 함수를 사용하면 작업을 편리하게 할 수 있다.

int InetPton (int af, const PCTSTR src, void* dst);

 

하지만, 오직 IP 주소 형태의 문자열만 처리할 수 있으므로 도메인 네임이나 DNS 조회등은 수행하지 않는다.

getaddrinfo 함수는 도메인 네임을 IP 주소로 변환하고 싶을 때 사용하는 것이다.

정의

int getaddrinfo (const char* hostname, const char* servname, const addrinfo* hints, addrinfo** res);

 

hostname 

널 종료 문자열로 도메인 조회를 할 이름 문자열을 가리켜야 한다. ex) "sanghun219.tistory.com"

 

servname

포트 번호 또는 서비스 이름을 널 종료 문자열로 지정해야 한다. ex) "80" , "http" => 80번 포트에 해당하는 sockaddr_in을 얻을 수 있다.

 

hints

호출자가 어떤 정보를 받고 싶은지를 기재해둔 addrinfo 구조체를 넘긴다. nullptr을 넘기면 모든 결과를 받을 수 있다.

 

res

함수의 결과를 반환받는 포인터 변수이며, 여러 개의 결과가 있을 수 있으므로 연결 리스트로 반환된다.

res는 그 첫째 원소가 된다.

addrinfo 정의

struct addrinfo

{

 int               ai_flags;

 int               ai_family;

 int               ai_socktype;

 int               ai_protocol;

 size_t           ai_addrlen;

 char*           ai_canon_name;

 sockaddr*     ai_addr;

 addrinfo*      ai_next;

};

 

ai_flags , ai_socktype, ai_protocol

hint에 요구 사항을 정의할 때 사용한다. 결과에 영향을 미치지 않으며 무시해도 좋다.

 

ai_family

addrinfo에 관련된 주소 패밀리를 나타낸다.

 

ai_addrlen

ai_addr이 가리키는 sockaddr의 길이 값이다.

 

ai_canonname

리졸브된 호스트명의 대표 이름을 담는다. hints로 ai_flags 필드에 AI_CANONNAME 플래그를 설정하여 된 경우에만

사용한다.

 

ai_addr

해당 주소 패밀리의 sockaddr을 담고 있다.

 

ai_next

연결 리스트상 다음 addrinfo를 가리킨다. 하나의 도메인 네임이 여러 IPv4 및 IPv6 주소를 가리킬 수 있으므로

원하는 sockaddr을 찾을 때까지 연결 리스트를 순회해야 한다.

hint로 ai_family를 지정해 주면 원하는 주소 패밀리의 것들만 받을 수 있다.

마지막 항목의 ai_next는 nullptr가 되어 마지막임을 나타낸다.

버퍼 해제

getaddrinfo()는 addrinfo를 반환할 때, 자체적으로 메모리를 할당해 주므로, 반환된 연결 리스트의 내용을 다 꺼내 쓴

다음엔 호출자가 직접 freeaddrinfo()를 호출해 메모리를 해제해 주어야 한다.

 

void freeaddrinfo (addrinfo* ai)

 

구현 오류 문제..

msdn과 여러 블로그를 통해서 예제를 따라서 해 본 결과... (이 글이 참조한 책 포함)

주소를 찾지 못하는 현상이 발생했다.

출처 : https://tapito.tistory.com/436

 

이 분의 포스팅에 따르면 현재 DNS 서버는 IP 주소에서 도메인으로 변환하는 Reserve DNS 기능을 지원하지 않기에

제대로된 결과가 나올수 없다고 한다.

 

물론, 이 문제가 아닐수도 있겠지만 .. 지금으로서 안되는 이유를 찾기가 어려울 것 같다.

이런 함수도 있다는 것을 알아두고 넘어가야겠다.

'게임 서버 프로그래밍 > 윈도우 소켓 프로그래밍' 카테고리의 다른 글

패킷과 직렬화  (0) 2021.02.15
Serializer 제작  (0) 2020.09.15
client , server 연습 ..  (0) 2020.02.22