네트워크 프로그래밍/C

[네트워크 프로그래밍/C] 주소정보의 표현

Justweon 2022. 2. 17. 16:51

IP주소와 PORT 번호 표현을 위한 구조체가 있습니다. 이 구조체를 중심으로 목적지 주소의 표현방법에 대해 알아보겠습니다. 물론 IPv4 기준으로 살펴보겠습니다.

IPv4 기반의 주소표현을 위한 구조체

주소정보를 담을 때는 다음 세 가지 물음에 답이 되도록 담아야 합니다.

  1. 어떠한 주소체계를 사용하는가?
  2. IP주소가 어떻게 되는가?
  3. PORT번호가 어떻게 되는가

위의 질문에 답이 되도록 다음과 같은 구조체가 정의되었습니다.

이 구조체는 bind 함수에 주소 정보를 전달하는 용도로 사용됩니다.

struct sockaddr_in {
    sa_family_t sin_family; // 주소체계 (Address Family)
    uint16_t sin_port; // 16비트 TCP/UDP PORT번호
    struct in_addr sin_addr; // 32비트 IP주소
    char sin_zero[8]; // 사용되지 않음
};

그리고 위의 구조체 in_addr은 다음과 같이 정의되어 있습니다. 이는 32비트 IP주소정보를 담을 수 있게 정의되어 있습니다.

struct in_addr {
    in_addr_t s_addr; // 32비트 IPv4 인터넷 주소
};

각 멤버에 대해 살펴보기 전에 생소한 자료형들을 살펴보겠습니다.

자료형 이름 자료형에 담길 정보 선언된 헤더파일
int8_t     singed 8-bit int     sys/types.h
uint8_t     unsigned 8-bit int (unsigned char)
int16_t     signed 16-bit int
uint16_t     unsigned 16-bit int (unsigned short)
int32_t     signed 32-bit int
uint32_t     unsigned 32-bit int (unsigned int)
sa_family_t     주소체계(address family)     sys/socket.h
socklen_t     길이정보(length of struct)
in_addr_t     IP주소정보, uint32_t로 정의되어 있음     netinet/in.h
in_port_t     PORT번호정보, uint16_t로 정의되어 있음

구조체 sockaddr_in의 멤버 분석

sin_family

프로토콜 체계마다 적용하는 주소체계가 다릅니다.

아래 표를 참조해 sin_family에 적용할 주소체계 정보를 저장해야 합니다.

주소체계(Address Family) 의    미
    AF_INET     IPv4 인터넷 프로토콜에 적용하는 주소체계
    AF_INET6     IPv6 인터넷 프로토콜에 적용하는 주소체계
    AF_LOCAL     로컬 통신을 위한 유닉스 프로토콜 주소체계

sin_port

16비트 PORT 번호를 저장합니다. 단, 네트워크 바이트 순서로 저장해야 하는데 이에 관해서는 이후 포스트에서 다루겠습니다.

sin_addr

32비트 IP주소정보를 저장합니다. 이 역시 네트워크 바이트 순서로 저장해야 합니다. 이 멤버를 정확히 파악하기 위해선 구조체 in_addr도 함께 살펴봐야 합니다. 그런데 in_addr의 유일한 멤버가 uint32_t로 선언되어 있으니 간단한 32비트 정수형으로 인식해도 괜찮습니다.

sin_zero

특별한 의미를 지니지 않는 멤버이고, 단순히 구조체 sockaddr_in의 크기를 구조체 sockaddr과 일치시키기 위해 삽입된 멤버입니다. 그러나 반드시 0으로 채워야 하고, 그러지 않으면 원하는 결과를 얻지 못합니다. 굳이 sockaddr를 쓰지 않고 sockaddr_in을 쓰는 이유는 sockaddr 구조체가 다소 불편한 형태로 정의되어 있기 때문입니다.