C/TCPIP 소켓 프로그래밍(윤성우 저)

TCP/IP 소켓 프로그래밍 8장 내용 확인문제

꾸준함. 2017. 6. 6. 18:52

1. 다음 중 DNS(Domain Name System)에 대한 설명으로 맞는 것을 모두 고르시오.


>a. DNS가 존재하기 때문에 IP를 대신해서 도메인 이름을 사용할 수 있다.

  c. 하나의 DNS 서버에 모든 도메인 정보가 다 등록되어 있지는 않다. 그러나 등록되지 않은 도메인의 IP주소도 얻어올 수 있 다.


  *틀린 설명

  b. DNS 서버는 사실 라우터를 의미한다. 라우터가 도메인 이름정보를 참조하여 데이터의 진로를 결정하기 때문이다

  

  ->DNS 서버는 도메인 이름을 IP주소로 변환하는 역할을 수행한다.


  d. DNS 서버는 운영체제에 따라서 구분이 된다. 즉, 윈도우 운영체제용 DNS서버와 리눅스용 DNS 서버는 구분이 된다.


  ->구분이 안된다


2. 아래의 대화를 읽고 동수가 제안한 해결책으로 문제가 해결될 수 있는지 말해보자. 참고로 이는 실제로 대학의 컴퓨터실에서 여러분이 직접 확인할 수 있는 내용이다.


  정수: 동수냐? 야! 우리학교 네트워크 망에 연결되어 있는 디폴트 DNS 서버가 다운되어서 이력서를 넣어야 할 회사들의 홈페이지에 접속이 안돼! 뭔가 방법이 없을까?


  동수: 인터넷과 연결은 되어있는데 DNS 서버만 다운된거야?


  정수: 응!해결책 뭐 없을까? 그냥 주변에 있는 PC방으로 달려가야 하나?

  동수: 그렇게까지 할 필요가 뭐 있냐? 내가 우리학교 DNS 서버 IP 주소를 불러줄 테니까, 네가 사용하는 컴퓨터의 디폴트 DNS 서버 주소를 변경해!


  정수: 그런다고 되냐? 디폴트 DNS 서버는 반드시 로컬 네트워크상에 연결되어 있어야 한다고!

  동수: 아냐! 지난번에 우리학교도 디폴트 DNS 서버가 죽으니까, 네트워크 관리자가 다른 DNS 서버의 IP주소를 알려주던데?


  정수: 그건 너네 학교에 DNS 서버가 여러 대 있으니까 가능했던 거야!

  동수: 그런가? 네 말이 맞는 것 같기도 하다. 그럼 얼른 PC방으로 달려가봐라!


>네트워크상에서의 특별한 제한이 없다면, 로컬 네트워크로 연결된 DNS 서버를 반드시 디폴트 DNS 서버로 지정해야 하는 것은 아니다. 즉, 굳이 PC방으로 안 가고 동수가 제안한 방법을 따라도 된다. 


3. 웹 브라우저의 주소 창에 www.orentec.co.kr을 입력해서 메인 페이지가 보이기까지의 과정을 정리해보자. 단, 웹 브라우저가 접속한 디폴트 DNS 서버에는 www.orentec.co.kr에 대한 IP주소가 등록되어 있지 않다고 가정하자.


>1. 호스트의 컴퓨터는 디폴트 DNS 서버에게 IP 주소를 물음

  2. 디폴트 DNS 서버는 IP 주소를 갖고 있지 않으므로, 상위 DNS 서버에게 IP 주소를 물음

  3. 상위 DNS 서버로부터 디폴트 DNS 서버는 IP 주소를 전달받음

  4. 디폴트 DNS 서버는 IP 주소를 호스트에게 전달

  5. 웹 브라우저는 전달 받은 IP 주소를 통해 서버에 접속



<구조체 hostent>

struct hostent

{

        char *h_name; //공식 도메인 이름

        char **h_aliases; //별칭의 도메인 이름

        int h_addrtype; //반환된 IP 정보가 IPv4 경우, AF_INET 반환

        int h_length; //반환된 IP 정보의 크기, IPv4 경우 4, IPv6 경우 16

        char **h_addr_list; //IP 주소정보, 이상의 경우 모두 반환

};


[예제]


리눅스 gethostbyname 함수 활용

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <arpa/inet.h>

#include <netdb.h>

 

void error_handling(char *message);

 

int main(int argc, char *argv[])

{

        int i;

        struct hostent *host;

        if (argc != 2)

        {

               printf("Usage::%s <addr>\n", argv[0]);

               exit(1);

        }

 

        host = gethostbyname(argv[1]); //main 함수를 통해서 전달된 문자열을 인자로 gethostbyname 함수를 호출하고 있다

        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 tyhpe:%s\n", (host->h_addrtype == AF_INET) ? "AF_INET" : "AF_INET6");

        //IP 주소 정보를 출력하고 있다. 그런데 이해할 없는 형변환을 진행하고 있다. 이는 구조체 hostent IPv4 뿐만 아니라 IPv6 기반의 주소정보도 저장할 있기 때문이다.

        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;

}

 

void error_handling(char *message)

{

        fputs(message, stderr);

        fputc('\n', stderr);

        exit(1);

}

 


리눅스 gethostbyaddr 함수 활용

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#include <arpa/inet.h>

#include <netdb.h>

 

void error_handling(char *message);

 

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]);

        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;

}

 

void error_handling(char *message)

{

        fputs(message, stderr);

        fputc('\n', stderr);

        exit(1);

}

 


윈도우 gethostbyname 함수 활용

#include <stdio.h>

#include <stdlib.h>

#include <WinSock2.h>

 

void ErrorHandling(char *message);

 

int main(int argc, char *argv[])

{

        WSADATA wsaData;

        int i;

        struct hostent *host;

        if (argc != 2)

        {

               printf("Usage:%s <addr>\n", argv[0]);

               exit(1);

        }

        if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)

               ErrorHandling("WSAStartup() error!");

 

        host = gethostbyname(argv[1]); //main 함수를 통해서 전달된 문자열을 인자로 gethostbyname 함수를 호출하고 있다

        if (!host)

               ErrorHandling("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");

        //IP 주소정보를 출력하고 있다. 그런데 이해할 없는 형변환을 진행하고 있다. 이는 hostent 구조체가 IPv4 뿐만 아니라 IPv6 기반의 주소정보도 저장할 있기 때문이다

        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]));

        WSACleanup();

        return 0;

}

 

void ErrorHandling(char *message)

{

        fputs(message, stderr);

        fputc('\n', stderr);

        exit(1);

}

 


윈도우 gethostbyaddr 함수 활용

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <winsock2.h>

 

void ErrorHandling(char *message);

 

int main(int argc, char *argv[])

{

        WSADATA wsaData;

        int i;

        struct hostent *host;

        SOCKADDR_IN addr;

        if (argc != 2)

        {

               printf("Usage:%s <IP>\n", argv[0]);

               exit(1);

        }

        if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)

               ErrorHandling("WSAStartup() error");

 

        memset(&addr, 0, sizeof(addr));

        addr.sin_addr.s_addr = inet_addr(argv[1]);

        host = gethostbyaddr((char*)&addr.sin_addr, 4, AF_INET);

        if (!host)

               ErrorHandling("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]));

        WSACleanup();

        return 0;

}

 

void ErrorHandling(char *message)

{

        fputs(message, stderr);

        fputc('\n', stderr);

        exit(1);

}

 


[참고] TCP/IP 소켓프로그래밍 윤성우 저

반응형