안녕하세요 삽잡이입니다.
이번 시간에는 바이트 정렬에 대해서 알아보도록 하겠습니다.
우선 바이트 정렬이 뭔지 알아보기 전에
변수 하나를 생성하고 그 안에 값을 채웠다고 해보겠습니다.
그러면 데이터는 어떻게 채워질까요?
채워지는 방법에는 두가지 방법이 있습니다.
int n = 0x1234 라는 값을 초기화 했다고 가정해봅시다.
n은 int형 변수로써 4개의 바이트를 가지고 있겠지요...
위의 그림과 같이 데이터가 저장됩니다.
그런데 왜 두가지가 표현됬을까요? 바로 두 방식이 모두 표준이기 때문입니다.
작은쪽의 주소에 끝값을 보관하고, 큰 쪽 주소에 앞쪽 값을 보관하고 있는 방법.
작은쪽의 주소에 앞쪽 값을 보관하고, 큰쪽 주소에 끝 값을 보관하고 있는 방법.
작은 쪽 주소에 끝값을 저장한다고 해서 리틀 엔디안 방식,
큰 쪽 주소에 끝값을 저장한다고 해서 빅 엔디안 방식이라고 부릅니다.
만일 모든 컴퓨터가 한 방식으로 데이터를 정렬한다면 상관이 없습니다.
그런데, 모든 컴퓨터가 각각 정렬하는 방식이 다르다면...
네트워크 통신을 할 때에 엉망 진창이 됩니다...
다른 텀퓨터에 데이터를 날리면 순서대로 정렬된 데이터를 받을 것인데
정렬 방식이 다르면 뒤집혀서 데이터를 받게 되지 않겠습니까...
단적인 예로 'A 문자 하나만 보내더라도
아스키코드로 65.. 0x0041입니다. 그런데 뒤집혀서 받으면 0x4100입니다.... 난리 나겠지요...
우리가 통신하는 컴퓨터가 어떤 방식으로 사용하는지는 네트워크가 모릅니다.
서로 상태를 모르는 컴퓨터끼리 사용하려는데 어떤 방식으로 바이트 정렬을 할지 어떻게 알까요.
따라서 규칙을 만들었습니다.
둘 사이에 통신할 때에는 통신하기 위한 약속 즉 네트워크 표준이 있습니다.
TCP/IP 프로토콜의 네트워크 바이트 표준은 바로 '빅 엔디안'으로 정했지요.
우리의 윈속(WIndow Socket)표준은 빅 엔디안이라는 것을 알고 있기 때문에
리틀 엔디안은 데이터를 보내게 될 때 변환하여야합니다.
만약, 빅 엔디안 방식을 사용하고 있다면 그대로 보낼 것이구요...
받는 PC 입장에서는 자신이 빅 엔디안 방식을 사용하고 있다면 그대로 데이터를 받겠고,
자기가 리틀 엔디안 방식을 사용한다면 변환해서 데이터를 받겠지요...
이런식으로 통신을 하게 됩니다.
네트워크가 빅 엔디안 방식을 표준으로 사용한다고 했는데,
내 컴퓨터가 리틀 엔디안이던 빅 엔디안이던 통신하는 방식이 같다면...
변환하는 작업을 하던 방법이 상관 없지 않겠습니까?
즉, 네트워크 방식은 빅 엔디안 방식인데,
통신하는 PC들 끼리 같은 방식을 사용하고 있다면 변환할 필요가 없다는 것입니다.
그래서 실질적으로 통신을 할 때에는 변환 작업을 많이 하지 않습니다.
하지만, '이기종'이라고 해서 바이트 정렬이 서로 다른 이기종 간에 통신을 할 때에는
아주 민감하게 잘 처리해야합니다.
우리가 사용하는 PC는 거의 intel 계열이고,
우리가 사용하는 핸드폰은 거의 ARM 계열로 만들어져 있습니다.
그런데 이 두 놈들이 모두 리틀 엔디안 방식을 사용하지요...
특수한 놈들만 빅 엔디안 방식을 사용하기 때문에 굳이 변환 작업을 많이 하지 않는다는 소리입니다.
하지만 중요합니다.
네트워크 통신을 하는데 무조건 이 규칙은 지켜줘야합니다.
'이기종'간에 데이터를 날릴 때에는 엄청나게 변환 작업을 해줘야합니다...
그렇지 않으면 데이터가 변질되니까요!
그런데 보낼 때마다 바이트 정렬을 해야한다면 비효율적이고 성능도 좋지 않겠군요...
그래도 중요합니다.
대표적인 함수로는
htons, htonl, ntohs, ntohl 와같은 함수가 있습니다.
호스트가 리틀 엔디안 방식을 쓰고 있으니 네트워크 방식으로 2, 4바이트로 바꾸겠다는 함수와
네트워크 상의 데이터를 호스트형 2, 4바이트로 바꾸겠다는 각가의 함수입니다.
만약, 변환 자체가 일어나지 않는다면 그대로 진행되구요...
개념에 대해서 빠삭하게 알도록 합시다...
물론 저의 설명이 빈약하겠지만 말입니다...
부족한 것은 구글링으로.. 허허...
이상 삽잡이였습니다!
'삽질의 현장 > - 네트워크 프로그래밍' 카테고리의 다른 글
#006_Window_Network_IP, DNS (0) | 2015.10.02 |
---|---|
#005_Window_Network_구조체 멤버 정렬 (0) | 2015.10.02 |
#003_Window_Network_ 윈도우 소켓 초기화 및 종료 (0) | 2015.10.02 |
#002_Window_Network_ Intro (TCP/IP 4계층) (0) | 2015.10.01 |
#001_Window_Network_ Intro (라우터) (0) | 2015.10.01 |