8.도메인 이름과 인터넷 주소

#. Domain NameSystem

IP주소와 도메인 이름 사이에서의 변환을 수행하는 시스템을 가리켜 'DNS(Domain Name System)'라 하며, DNS의 중심에는 DNS서버가 있다.

    

 #.도메인이름이란?

인터넷에서 서비스를 제공하는 서버들 역시 IP주소로 구분이 된다.

그러나 기억하기 쉽지 않아 기억하기 좋고 표현하기도 좋은 형태의 도메인 이름이라는 것을 IP주소에 부여해 사용하고 있다.

 

 

#.DNS서버

네이버의 IP주소인 222.122.195.5를 직접 입력하여 네이버의 메인페이지에 접속하는 것과 www.naver.com 의 입력틍 통해 접속하는 것에 어떤 차이점이 있는 것일까?네이버의 메인 페이지에 접속한다는 점에서 차이가 없지만, 접속의 과정에는 차이가 있다. 도메인 이름은 해당 서버에 부여된 가상의 주소이지 실제 주소가 아니다. 때문에 가상의 주소를 실제주소로 변환하는 과정을 거쳐서 네이버에 접속해야 한다. 그렇다면 어떻게 도메인 이름을 IP주소로 변환해야 할까? 이러한 변환을 담당하는 것이 DNS서버이니, DNS서버에게 변환을 요청하면 된다

 

모든 컴퓨터에는 디폴트 DNS서버의 주소가 등록되어 있는데, 바로 이 디폴트 DNS 서버를 통해서 도메인 이름에 대한 IP주소 정보를 얻게 된다. 즉 인터넷 브라우저 주소창에 도메인 이름을 입력하면 인터넷 브라우저는 해당 도메인 이름의 IP주소를 디폴트 DNS서버를 통해 얻게 되고, 그 다음에야 비로소 서버로의 실제 접속에 들어가게 되는 것이다

 

디폴트 DNS서버가 모든 도메인의 IP주소를 알고 있지는 않다. 그러나 디폴트 DNS서버는 모르면 물어서라도 가르쳐 준다. 디폴트 DNS서버는 자신이 모르는 정보에 대한 요청이 들어오면 한 단계 상위 계층에 있는 DNS서버에게 물어본다.

이러한 식으로 계속 올라가다 보면 최상위 DNS서버인 Root DNS서버에게까지 질의가 전달되는데, Root DNS서버는 해당 질문을 누구에게 재 전달해야할지 알고 있다. 그래서 자신보다 하위에 있는 DNS서버에게 다시 질의를 던져서 결국 IP주소를 얻어내며, 그 결과는 질의가 진행된 반대 방향으로 전달이 되어 결국에는 질의를 시작한 호스트에게 IP주소가 전달된다. 이렇듯 DNS는 계층적으로 관리되는 일종의 분산 데이터베이스 시스템이다.

 

#.IP주소와 도메인 이름 사이의 변환

 

프로그램상에서 도메인 이름을 쓸 필요가 있는가?

 

시스템을 운영하는 동안 IP주소를 계속 유지하는 것은 쉬운 일이 아니다.

특히 ISP 서비스를 제공하는 통신사업자의 도움으로 IP를 유지하고 있다면 시스템과 관련된 여러가지 이유로 IP주소의 변경은 언제든지 발생할 수 있다.

 

IP주소는 도메인 이름에 비해 상대적으로 변경의 확률이 높다. 때문에 IP주소를 바탕으로 프로그램을 작성하는 것은 좋은 방법이 아니다. 그렇다면 어떤 방법을 생각할 수 있을까? 도메인 이름은 일단 등록하고 나면 평생 유지가 가능하니, 이를 이용해서 코드를 작성하는 편이 나을 수 있다. 이렇게 되면 프로그램이 실행될 때마다 도메인 이름을 근거로 IP주소를 얻어온 다음에 서버에 접속을 하게 되니, 서버의 IP주소로부터 클라이언트 프로그램은 자유로울 수 있다. 그래서 IP주소와 도메인 이름 사이의 변환 함수가 필요한 것이다.

 

 

 #.도메인 이름을 이용해서 IP주소 얻어오기

 

 다음 함수를 이용하면 문자열 형태의 도메인 이름으로부터 IP의 주소정보를 얻을 수 있다.

 

 #include <netdb.h>   

struct hostent* gethostbyname(const char* hostname);

// 성공 : hostent 구조체 변수의 주소 값

// 실패 : NULL 포인터

 

hostent 구조체는 다음과 같이 정의되어 있다.

 

struct hostent

{

char* h_name;          // official name

char** h_aliases;       // alias list

int h_addrtype;          // host address type

int h_length;              // address length

char** h_addr_list    // address list

}

 

위의 구조체 정의를 보니, IP정보만 반환되는 것이 아니라, 여러 가지 다른 정보들도 덤으로 반환되는 것을 알 수 있다.

 

*h_name

공식 도메인 이름(Official domain name)'이라는 것이 저장된다.

공식 도메인 이름은 해당 홈페이지를 대표하는 도메인 이름이라는 의미를 담고 있지만,

실제 우리에게 잘 알려진 유명 회사의 도메인 이름이 공식 도메인 이름으로 등록되지 않은 경우가 많다.

 

*h_aliases

같은 메인 페이지인데도 다른 도메인 이름으로 접속할 수 있는 경우가 있다.

하나의 IP에 둘 이상의 도메인 이름을 지정하는 것이 가능하기 때문에, 공식 도메인 이름 이외에 해당 메인 페이지에 접속할 수 있는 다른 도메인 이름의 지정이 가능하다.

이들 정보는 h_aliases를 통해 얻을 수 있다.

 

*h_addrtype

gethostbyname함수는 IPv4뿐만 아니라 IPv6까지 지원한다.

때문에 h_addr_list로 반환된 IP주소의 주소체계에 대한 정보를 이 멤버를 통해 반환한다.

IPv4인 경우 AF_INET이 저장된다.

 

*h_length

함수호출의 결과로 반환된 IP주소의 크기정보가 담긴다. IPv4인 경우 4바이트이므로 4가 저장되고, IPv6인 경우 16바이트이므로 16이 저장된다.

 

*h_addr_list

이것이 가장 중요한 멤버이다. 이 멤버를 통해 도메인 이름에 대한 IP주소가 정수의 형태로 반환된다.

참고로 접속자수가 많은 서버는 하나의 도메인 이름에 대응하는 IP를 여러 개 둬서, 둘 이상의 서버로 부하를 분산시킬 수 있는데, 이러한 경우에도 이 멤버를 통해서 모든 IP의 주소정보를 얻을 수 있다.

 

 

gethostbyaddr 함수 예제

결과

 

 

gethostbyname 함수 예제

결과

 

 

 

 

[출처] : 윤성우 저, "열혈강의 TCP/IP 소켓 프로그래밍", 오렌지미디어