엔디안이 다른 시스템끼리 데이터를 주고받을 때, 호스트 바이트 순서와 네트워크 바이트 순서(빅 엔디안)를 바꿔 주는 함수를 알아보자.
네트워크는 빅 엔디안으로 약속했으므로, 보내기 전에 호스트 순서를 네트워크 순서로 바꾸고, 받은 뒤에 다시 호스트 순서로 바꾼다.
| 함수 | 이름의 뜻 | 하는 일 |
|---|---|---|
htons |
host to network short | 16비트를 호스트 순서에서 네트워크 순서로 |
htonl |
host to network long | 32비트를 호스트 순서에서 네트워크 순서로 |
ntohs |
network to host short | 16비트를 네트워크 순서에서 호스트 순서로 |
ntohl |
network to host long | 32비트를 네트워크 순서에서 호스트 순서로 |
long은 이름일 뿐이고, 크기는 32비트이다. (uint32_t를 쓴다.)#include <stdio.h>
#include <stdint.h>
#include <arpa/inet.h>
int main(void) {
uint16_t s = 0x1234;
uint32_t l = 0x12345678;
printf("htons: 0x%04x -> 0x%04x\n", s, htons(s));
printf("htonl: 0x%08x -> 0x%08x\n", l, htonl(l));
printf("ntohs(htons): 0x%04x\n", ntohs(htons(s)));
printf("wrong htonl(s): 0x%08x\n", htonl(s));
return 0;
}
리틀 엔디안 PC에서의 출력
htons: 0x1234 -> 0x3412
htonl: 0x12345678 -> 0x78563412
ntohs(htons): 0x1234
wrong htonl(s): 0x34120000
printf로 찍으면 값이 뒤집혀 보인다. 메모리에는 12 34 56 78(빅 엔디안) 순서로 놓였지만, 리틀 엔디안 CPU가 그 바이트를 숫자로 읽기 때문이다.htonl을 쓰면 크기가 맞지 않아 엉뚱한 값이 된다. 크기에 맞는 함수를 쓴다.<arpa/inet.h> 대신 <winsock2.h>를 쓰고 ws2_32 라이브러리를 연결한다.▼ 엔디안 방식에 구애 받지 않는 C 코드 작성하기