2014년 12월 11일 목요일

TCP/IP 소켓 프로그래밍 8강

목표가 올해안에 22강까지 공부하는 건데.
7강이 짧아서 8강까지 공부했다 ㅎㅎ
8강은 DNS에 대해 알아본다
DNS는 (Domain Name System)이다.
도메인 이름 <-> IP주소 를 변환 시켜주는 시스템이다.
모든 컴퓨터에는 디폴트 DNS 서버의 주소가 등록되어 있는데,
먼저 이 디폴트 DNS서버를 통해 IP주소를 받고,
여기에 없으면 상위 DNS 서버로 올라가서 다른 DNS 서버에서 IP주소를 받아와서 알려준다.

소켓 프로그래밍을 하기 위해서는 IP주소와 포트 번호를 알아야 하는데
문제는 이 IP주소가 자주 바뀐다는 것이다.
이 바뀌는 IP를 계속 찾아서 프로그램에 넣을 수도 없는 노릇이니
서비스가 망하지 않는한 바뀌지 않는 도메인 주소를 가지고 프로그래밍을 하는 것이 합당할 것이다.
그럴려면 도메인 이름 -> IP주소로 변환시켜주는 함수가 필요하다.

#include <netdb.h>
struct hosttent *gethostbyname(const char* hostname);

변환하고자 하는 도메인의 이름을 문자열 형태로 전달하면 해당 도메인의 IP주소를 반환한다

단, 구조체에 담겨서 반환이 되니 구조체를 알아보자.
struct hostnet
{
char* h_name;      //공식 도메인 이름
char** h_aliases;   //하나의 IP로 접속 가능한 다른 도메인의 이름
int h_addrtype;       //IPv4, IPv6 같은 주소 체계를 저장
int h_length;           //IP 주소의 크기 정보
char** h_addr_list;  //도메인 이름에 대한 IP주소 저장
}

소스를 보자
int main(int argc, char *argv[])
{
int i;
struct hostent *host;
if(argc!=2) {
printf("Usage : %s <addr>\n", argv[0]);
exit(1);
}
//main 함수를 통해서 전달 된 문자열을 인자로 gethostbyname함수 호출
host=gethostbyname(argv[1]);
if(!host)
error_handling("gethost... error");
        //공식 도메인을 출력한다.
printf("Official name: %s \n", host->h_name);

for(i=0; host->h_aliases[i]; i++)
printf("Aliases %d: %s \n", i+1, host->h_aliases[i]);
//ip주소 타입
printf("Address type: %s \n", 
(host->h_addrtype==AF_INET)?"AF_INET":"AF_INET6");
        //ip주소 정보 출력
for(i=0; host->h_addr_list[i]; i++)
printf("IP addr %d: %s \n", i+1,
inet_ntoa(*(struct in_addr*)host->h_addr_list[i]));
return 0;
}

이번에는 반대로 IP주소 -> 도메인 주소를 알려주는 함수다.

#include <netdb.h>
struct hostent* gethostbyaddr(const char* addr, socklen_t len, int family);

-addr :  ip주소를 지나는 in_addr 구조체 변수의 포인터 전달, IPv4 이외의 다양한 정보를 전달 받을 수 있도록 일반화 하기 위해서 매개변수를 char형 포인터로 선언
-len :  첫 번째 인자로 전달된 주소 정보의 길이, IPv4의 경우 4, IPv6의 경우 16을 전달.
-family :  주소체계 정보 전달, IPv4의 경우 AF_INET, IPv6의 경우 AF_INET6 전달.

소스를 보자.
int main(int argc, char *argv[])
{
int i;
struct hostent *host;
struct sockaddr_in addr;
if(argc!=2) {
printf("Usage : %s <IP>\n", argv[0]);
exit(1);
}

memset(&addr, 0, sizeof(addr));
addr.sin_addr.s_addr=inet_addr(argv[1]);
        //IP -> 도메인으로 변환하는 함수
host=gethostbyaddr((char*)&addr.sin_addr, 4, AF_INET);
if(!host)
error_handling("gethost... error");

printf("Official name: %s \n", host->h_name);

for(i=0; host->h_aliases[i]; i++)
printf("Aliases %d: %s \n", i+1, host->h_aliases[i]);

printf("Address type: %s \n",
(host->h_addrtype==AF_INET)?"AF_INET":"AF_INET6");

for(i=0; host->h_addr_list[i]; i++)
printf("IP addr %d: %s \n", i+1,
inet_ntoa(*(struct in_addr*)host->h_addr_list[i]));
return 0;
}

위 2개 함수는 윈도우에서도 동일하다.

역시 소스 코드를 받아서 확인해보자.
소스 코드 받기

다음 강에는 소켓의 다양한 옵션에 대해 알아볼 것이다~

댓글 없음:

댓글 쓰기