[Socket] 도메인 이름과 인터넷 주소

Domain Name System(DNS)

도메인 이름이란, 기억하기도 좋고 표현하기도 좋은 형태로 IP주소에 부여하는 것으로 IP주소를 대신한다. 실제 접속에 사용되는 주소는 아니고, 이 정보는 IP로 변환이 되어야 접속이 가능하다. 도메인 이름은 해당 서버에 부여된 가상의 주소이지 실제주소가 아니다.

DNS 서버

도메인 이름을 IP로 변환해주는 서버이다. 모든 컴퓨터에는 디폴트 DNS 서버의 주소가 등록되어 있는데, 이를 통해서 도메인 이름에 대한 IP주소 정보를 얻게 된다.

도메인 이름을 이용해서 서버에 접속하면, 접속 이전에 DNS 서버에 해당 도메인의 IP주소를 묻게 되고(이 때 모른다면, 다른 DNS 서버에 물어서라도 가르쳐준다.), 그 결과로 얻게 된 IP를 이용해서 서버에 접속하게 된다.

DNS는 계층적으로 관리되는 일종의 분산 데이터베이스 시스템이다.

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

gethostbyname

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

#include <netdb.h>

struct hostent* gethostbyname(const char* hostname);
//성공 시 hostent 구조체 변수의 주소 값, 실패 시 NULL 포인터 return

이 함수의 인자로 도메인의 이름 정보를 전달하면, 해당 도메인의 서버정보가 hostent구조체 변수에 채워지고, 그 변수의 주소값이 반환된다.
connect() 함수를 실행하기 전에 실행되고, 이를 2번째 arg에 넣게 된다.

hostent구조체는 다음과 같다.

struct hostent{
    char* h_name;
    char** h_aliases;
    int h_addrtype;
    int h_length;
    char** h_addr_list;
}
  • h_name : 공식 도메인 이름
  • h_aliases : 별칭의 도메인 이름
  • h_addrtype : 반환된 IP의 주소체계(IPv4/IPv6) 정보. IPv4의 경우, AF_INET
  • h_length : 반환된 IP정보의 크기. IPv4 = 4, IPv6 = 16
  • h_addr_list : 도메인 이름에 대한 IP주소가 정수의 형태로 반환

IP주소는 도메인 이름에 비해 상대적으로 변동이 심하다. 때문에 프로그램 코드상에서 서버의 IP주소를 직접 입력한다면, 서버의 IP가 변경될 때마다 컴파일을 다시 해야하는 번거로운 상황이 발생하게 된다. 따라서, 변동이 덜한 도메인 이름을 이용해 서버가 실행될 때마다 IP를 얻어오는 것이 더 효율적이다.

gethostbyaddr

이 함수는 IP주소를 이용해서 도메인 정보를 얻어오는 함수이다.

#include <netdb.h>

struct hostent* gethostbyaddr(const char* addr, socklen_t len, int family);
//성공 시 hostent 구조체 변수의 주소 값, 실패 시 NULL 포인터 return
  • addr : IP주소를 지니는 in_addr 구조체 변수의 포인터
  • len : 첫 번째 인자로 전달된 주소정보의 길이. IPv4 = 4, IPv6 = 16
  • family : 주소체계 정보. IPv4 = AF_INET, IPv6 = AF_INET6