2015년 12월 28일 월요일

C 언어 - 네트워크 프로그래밍 (IPv4 와 IPv6 대응)

IPv4 와 IPv6


IPv4 주소의 예

  • 192.168.0.1


IPv6 주소의 예

  • 2001:0DB8:0000:0000:0000:0000:1428:57ab


Socket API 상 주소는 sockaddr 구조체로 대표되며 IPv4 는 sockaddr_in 에 담아야 하고 IPv6 는 sockaddr_in6 에 담아야 한다.

IPv6 에서 주소 값의 확장 등의 이유로 sockaddr_in 과 sockaddr_in6 는 구조체 모양이나 크기가 다르다.

sockaddr_in 과 sockaddr_in6 는 모두 family 라는 멤버 변수가 포함되어 있고 Socket API 는 이 family 값을 확인하여 해당 구조체가 sockaddr_in 인지 sockaddr_in6 인지 확인할 수 있다.

IPv4 와 IPv6 를 대응하기 위한 Socket API 들이 이미 존재한다.


  • getaddrinfo()
  • inet_pton()
  • inet_ntop()

API 설명



getaddrinfo()


int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res);

참고: http://man7.org/linux/man-pages/man3/getaddrinfo.3.html

매개변수:


  • node : IP 주소 등
  • service : Port 번호 등
  • hints : node 와 service 를 이용해 결과 값을 만들기 위한 정보
  • res : 결과값 (반드시 freeaddrinfo() 로 메모리 해제해야 함)


설명:

기존의 sockaddr_in 을 직접 입력하는 방식이 아닌 node 와 service 및 hints 를 이용해 socket() 함수 및 bind() 함수에 사용할 수 있는 정보를 얻을 수 있다.
node 와 service 는 일반적으로 IP주소와 Port번호로 대입되며 NULL 을 입력하면 해당 부분은 INADDR_ANY 와 유사한 효과를 볼 수 있다.
장점은 node 에 IPv4 나 IPv6 주소 또는 domain 이름 (예: www.google.com) 등 어떠한 주소 체계도 처리해 준다.
해당 함수로 인해 개발자가 대응할 부분이 많이 줄어들었다.

예) getaddrinfo() 를 이용해 remote 서버의 주소 정보를 얻고 그에 맞는 socket 을 생성
struct addrinfo hints;struct addrinfo * res = NULL;int sock;char buffer[1024] = {0,};
memset(&hints, 0, sizeof(hints));hints.ai_family = AF_UNSPEC;hints.ai_socktype = SOCK_STREAM;if (getaddrinfo("127.0.0.1", "9000", &hints, &res) < 0) { perror("getaddrinfo()"); return 1;}sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);if (sock < 0) { perror("socket()"); return 1;}
(생략)
freeaddrinfo(res);

inet_pton()


int inet_pton(int af, const char *src, void *dst);

참고: http://man7.org/linux/man-pages/man3/inet_pton.3.html

매개변수:


  • af : AF_INET 또는 AF_INET6
  • src : IPv4 또는 IPv6 주소
  • dst : src 가 변환되어 채워질 addr 구조체 (in_addr 또는 in6_addr)


설명:

사람이 읽을 수 있는 192.168.0.1 또는 2001:0DB8:0000:0000:0000:0000:1428:57ab 등의 주소를 컴퓨터가 인식할 수 있는 주소 형태로 변경

inet_ntop()


const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);

참고: http://man7.org/linux/man-pages/man3/inet_ntop.3.html

매개변수:


  • af : AF_INET 또는 AF_INET6
  • src : addr 구조체 (in_addr 또는 in6_addr)
  • dst : src 가 변환되어 채워질 문자열 버퍼
  • size : 문자열 버퍼의 크기


설명:

inet_pton() 과 반대로 in_addr 또는 in6_addr 을 사람이 읽을 수 있는 문자열로 변환

Cross platform


위 함수들은 winsock API 에도 동일하게 존재한다. (변수 타입이 미묘하게 다를 수는 있음)
Windows XP 의 경우 IPv4 대응 함수인 inet_aton() 과 inet_ntoa() 만 사용 가능하다.


댓글 없음:

댓글 쓰기