본문 바로가기

소켓 프로그래밍/서버와 클라이언트

* 바이트 순서

먼저 바이트 순서라는 것은 시스템이 내부적으로 데이터를 표현하는 방법을 말한다. 크게 두 가지의 방식으로 나뉘는데 
리틀 엔디안(Little-Endian)과 빅 엔디안(Big-Endian)이다. 0x12345678을 두 가지 방식으로 표현해보자.

빅 엔디안 : 상위 바이트의 값(왼쪽에 있는 1)이 메모리상에 먼저(번지수가 작은 위치) 표시되는 방법을 말한다. 

빅 엔디안 표현 방식

리틀 엔디안 : 하위 바이트의 값(오른쪽에 있는 8)이 메모리상에 먼저(번지수가 작은 위치) 표시되는 방법을 말한다.

리틀 엔디안 표현 방식

시스템이 내부적으로 데이터를 처리하는데 있어서 어떠한 방식을 사용하는지는 CPU에 따라 다르다. 이를 "호스트 바이트 순서(host byte order)"라고 하는데 CPU마다 다른 문제로 일정하지 않다는 것이 문제가 된다. 바이트 순서가 다르다면 전달할 때의 값과 받아들이는 값이 다르게 표현이 되기 때문에 문제가 발생할 수 있다. 이러한 문제점 때문에 네트워크를 통해 데이터가 전송될 경우에는 통일된 방식으로 보내자고 약속을 하였는데 이것이 바로 네트워크 바이트 순서이다. 네트워크 바이트는 빅 엔디안 방식만을 사용하기로 약속되어 있다. 따라서 위의 구조체는 네트워크를 통해 데이터가 전송이 되기 때문에 빅 엔디안 방식을 사용한다. 

바이트 순서 변환을 위한 함수
'h' = host byte order
'n' = network byte order
's' = short (16bit)
'l' = long (32bit)
htons란? 호스트 바이트 순서(host byte order)를 네트워크 바이트(network byte order) 순서로 바꾸어주는 것을 의미하고 s는 short 형태로 변환을 의미한다. port는 2바이트 이므로 short을 사용하며 IP주소는 4바이트를 사용하기 때문에 long을 사용한다.

아래의 코드로 자신의 CPU가 어떠한 바이트 순서를 사용하는지 알아보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <Winsock2.h>
#pragma comment(lib, "ws2_32.lib")
 
int main()
{
    short host_port_order = 0x1234;
    short net_port_order = 0;
 
    long host_add_order = 0x12345678;
    long net_add_order = 0;
 
    net_port_order = htons(host_port_order);
    net_add_order = htonl(host_add_order);
 
    printf("Host ordered port : %x \n", host_port_order);
    printf("Network ordered port : %x \n", net_port_order);
 
    printf("Host ordered address : %x \n", host_add_order);
    printf("Network ordered address : %x \n", net_add_order);
}
cs

 

아래와 동일한 출력 결과가 나온다면 CPU는 리틀 엔디안 방식을 사용하고 있다는 것이다.

출력 결과

 

'소켓 프로그래밍 > 서버와 클라이언트' 카테고리의 다른 글

* Iterative 서버  (0) 2020.07.14
* TCP / IP 4계층  (0) 2020.07.13
* 주소 체계와 데이터 설정  (0) 2020.07.08
* 소켓의 생성과 프로토콜  (0) 2020.07.08
1) Hello World 서버  (1) 2020.07.08