개요
엔디언(Endianness)은 컴퓨터의 메모리와 같은 1차원의 공간에 여러 개의 연속된 대상을 배열하는 방법을 뜻하며, 바이트를 배열하는 방법을 특히 바이트 순서(Byte order)라 합니다.
엔디언은 보통 큰 단위가 앞에 나오는 빅 엔디언(Big-endian)과 작은 단위가 앞에 나오는 리틀 엔디언(Little-endian)으로 나눌 수 있습니다.
네트워크 바이트 순서 (Network Byte Order)
서로 다른 바이트 순서를 사용하는 시스템이 서로 통신을 하기 위해서, 인터넷 프로토콜은 네트워크상에서 데이터를 전송할 때 빅 엔디언을 사용하도록 규정하고 있습니다. 따라서 빅 엔디언을 네트워크 바이트 순서라고 부르기도 합니다.
바이트 순서(Byte Order) 라이브러리
시스템이 네트워크 바이트 순서를 이용해 통신을 할 수 있도록 C 언어는 라이브러리를 통해 바이트 순서를 변환하는 함수를 제공합니다.
일반적으로 사용되는 네트워크 바이트 순서로 변경을 위한 함수는 htons()
, ntohs()
, htonl
, ntohl
입니다.
이들 함수 내의 h
는 host 바이트 순서를 의미합니다. n
은 network 바이트 순서를 의미합니다. s
와 l
은 함수가 다루는 정수의 크기를 의미하며 s
는 16 bit, l
은 32 bit 정수를 의미합니다.
즉 htons
는 16 bit 정수형을 호스트 바이트 순서에서 네트워크 바이트 순서로 변환합니다. 이들 함수는 리틀 엔디언 시스템에서만 실제로 바이트 순서를 변환합니다. 빅 엔디언 시스템은 이미 네트워크 바이트 순서를 사용하기 때문에 아무런 작용을 하지 않습니다.
이들 함수를 사용하기 위해서는 <arpa/inet.h>
헤더를 포함해야 합니다. 이 함수들은 표준 C/C++ 언어 라이브러리이지만, 옛 표준이기 때문에 현재 널리 사용되는 64 Bit 자료형을 변환하는 함수는 제공하지 않고 있습니다. 따라서 이를 해결하기 위해서는 비표준 라이브러리이지만 glibc에서 제공하는 <endian.h>
헤더를 추가하여 이 라이브러리에서 포함되어 있는 htobe16
, htole16
, be16toh
, le16toh
, htobe32
, htole32
, be32toh
, le32toh
, htobe64
, htole64
, be64toh
, le64toh
를 사용합니다.
이 함수들은 현재 CPU (호스트)가 사용하는 바이트 순서를 리틀 엔디언과 바이트 순서로 정수의 바이트 인코딩을 변환합니다.
함수 이름에 포함되어 있는 숫자(nn)는 함수가 처리하는 정수의 크기를 의미합니다. 즉, 16, 32 또는 64 bits입니다.
h
는 Host 바이트 순서를 be
는 빅 엔디언을 le
는 리틀 엔디언을 뜻합니다.
따라서, htobe64
는 호스트 바이트 순서의 64 비트 정수를 빅 엔디언 바이트 순서로 변환합니다.
바이트 순서 변환
이들 함수의 사용이 불가능할 경우, htonll()
, ntohll()
에 해당하는 함수를 직접 구현해 사용합니다.
#include <sys/types.h>
#include <netinet/in.h>
#include <inttypes.h>
#ifdef WORDS_BIGENDIAN
#define htonll(x) (x)
#define ntohll(x) (x)
#else
#define htonll(x) ((((uint64_t)htonl(x)) << 32) + htonl(x >> 32))
#define ntohll(x) ((((uint64_t)ntohl(x)) << 32) + ntohl(x >> 32))
#endif
참고
'프로그래밍 언어 > C' 카테고리의 다른 글
[C] realpath (0) | 2021.05.28 |
---|---|
비트단위 연산과 비트 필드 (0) | 2019.04.01 |
콘솔 다루기 (Escape Sequence) @ C (2/2) (0) | 2018.11.26 |
콘솔 다루기 (Escape Sequence) @ C (1/2) (0) | 2018.11.23 |