티스토리 뷰
* 본 포스팅은 한국소프트웨어진흥원 출처의 리눅스 네트워크 프로그래밍 PDF 파일을 토대로 작성되었습니다.
* 개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있음을 밝힙니다.
사전에 깔고 들어가는 정보
※ 4 byte의 IP 주소를 편의에 따라 도메인 주소 또는 10진수(demical) 형태로 표현함
○ IP 주소
- 10진수 표현의 저장에는 15개의 문자로 구성된 문자열 변수가 사용됨
- IP 데이터그램을 네트워크 상에서 전송할 때 IP 헤더에는 2진수(binary) IP주소만 사용
IP 주소변환
예제(ip_conv.c)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #include "stdio.h" #include "netinet/in.h" //inet_pton, inet_ntop 함수가 포함된 헤더파일 void main(int argc, char *argv[]) { struct in_addr addr; //2진수 IP 주소의 저장을 위한 구조체 사용 char buf[20]; //10진수 IP 주소의 저장을 위한 임시 변수 printf("demical IP addr : %s\n", argv[1]); //입력받은 10진수 IP 주소를 명시 inet_pton(AF_INET, argv[1], &addr.s_addr); printf("inet_pton(%s) : 0x%x\n", argv[1], addr.s_addr); //입력받은 값을 2진수 IP주소로 변환하여 addr 구조체에 저장 inet_ntop(AF_INET, &addr.s_addr, buf, sizeof(buf)); printf("inet_ntop(0x%x) = %s\n", addr.s_addr, buf); //addr 구조체의 2진수 IP주소 값을 10진수로 변환하여 buf에 sizeof(buf)만큼 저장 } |
○ inet_pton() : 10진수 IP 주소를 2진수 IP 주소로 변환하는 함수
- inet_pton(AF_INET, 10진수 IP주소, 변환될 IP가 저장될 공간)
- 10진수로 표현된 IP 주소를 인자로 입력
- IPv6로 사용한다면 AF_INET6 를 인자로 준다.
○ inet_ntop() : 2진수 IP 주소를 10진수 IP 주소로 변환하는 함수
- inet_ntop(AF_INET, 2진수 IP주소, 변환될 IP가 저장될 공간(buf), buf의 크기)
- 2진수로 표현된 IP 주소를 인자로 입력
- IPv6로 사용한다면 AF_INET6 를 인자로 준다.
실행결과
도메인 주소변환
※ DNS 서버의 도움을 받아 도메인 네임으로 부터 IP 주소를 얻거나
IP 주소로 부터 도메인 네임을 얻음
※ 구조체 hostent : 호스트의 각종 정보를 저장한 구조체
1 2 3 4 5 6 7 8 | struct hostent { char *h_name //호스트 이름 char **h_aliases //호스트 별명들 int h_addrtype //호스트 주소의 종류 int h_length //주소의 길이 char **h_addr_list //IP 주소 리스트 }; |
○ gethostbyname() : 도메인 네임를 IP 주소로 변환하는 함수
- 도메인 네임을 문자열 형태로 입력
- 해당 호스트의 정보를 가진 hostent 구조체 포인터를 리턴
○ gethostbyaddr() : 2진수 IP 주소를 도메인 네임로 변환하는 함수
- IP 주소를 포함하고 있는 in_addr 구조체 포인터와 주소의 길이, 주소 타입 입력
- 해당 호스트의 정보를 가진 hostent 구조체를 리턴
※ 호스트의 정보를 얻기 위해서는 DNS 서버에서 Reverse DNS가 수행되어야 한다.
※ 그런데 최근 보안문제로 대부분의 DNS 서버가 Reverse DNS 기능을 제공하지 않는다.
2014. 05. 16 추가 내용
gethostbyname, gethostbyaddr 은 구식 방법으로써 현재 표준이 아니라고 합니다.
현재는 getnameinfo 함수가 표준으로써, getnameinfo 관련 링크를 첨부합니다. (영문)
http://man7.org/linux/man-pages/man3/getnameinfo.3.html
getnameinfo 함수에 대한 정보가 국내 사이트에 많지 않아서 조만간 직접 사용해보고 내용 추가하도록 하겠습니다.
gethostbyname 예제(domain_conv.c)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #include "stdio.h" #include "netinet/in.h" #include "netdb.h" //hostent 구조체와 gethostname 함수 포함 헤더 void main(int argc, char *argv[]) { struct hostent *host; struct in_addr addr; int i; char buf[20]; host = gethostname(argv[1]); if(!host) { printf("gethostbyname fail\n"); exit(0); } printf("호스트 이름 : %s\n", host->h_name); printf("호스트 주소타입 번호 : %d\n", host->h_addrtype); printf("호스트 주소의 길이 : %d\n", host->h_length); for(i=0; host->h_addr_list[i]; i++) { memcpy(&addr.s_addr, host->h_addr_list[i], sizeof(addr.s_addr)); inet_ntop(AF_INET, &addr, buf, sizeof(buf)); printf("IP 주소(%d 번째) : %s", i+1, buf); } for(i=0; host->h_aliases[i]; i++) { printf("호스트 별명(%d 번째) : %s", i+1, host->h_aliases[i]); } } |
실제로 gcc 로 컴파일 하면 컴파일에는 성공하나 프로그램을 구동하면
DNS 정보를 얻어 못하는 건지 어딘가에 문제가 있는지
gethostbyname fail 이 뜨는 것을 확인 할 수 있다.
'개인공부 > 소켓 프로그래밍' 카테고리의 다른 글
리눅스 소켓 프로그래밍 08 : TCP 서버 작성절차, 함수 (0) | 2014.02.11 |
---|---|
리눅스 소켓 프로그래밍 07 : TCP 클라이언트 프로그램 예제 (0) | 2014.02.08 |
리눅스 소켓 프로그래밍 06 : TCP 클라이언트 작성절차, 함수 (0) | 2014.02.07 |
리눅스 소켓 프로그래밍 04 : 소켓주소 구조체 (0) | 2014.02.02 |
리눅스 소켓 프로그래밍 03 : 디스크립터 확인 예제 (2) | 2014.02.02 |
리눅스 소켓 프로그래밍 02 : 소켓 socket() 함수 (3) | 2014.02.02 |
리눅스 소켓 프로그래밍 01 : 소켓(Socket) 정의 (0) | 2014.02.02 |