본문 바로가기

별걸다하는 IT/네트워크_소켓_통신

[endian 2탄]리틀엔디안 vs 빅엔디안, 각 엔디안방식의 장단점, NBO(network byte order), CPU별 엔디안 차이.

반응형

안녕하세요!

드디어 오랜만에 찾아온 엔디안 방식 2탄입니다. 

 

저번시간에는 엔디안의 개념적인 부분을 다뤘었는데요.

- 바이트 오더 vs 비트 오더

- 빅 엔디안 방식 vs 작은 엔디안 방식 

요렇게 살펴봤어요.

 

▼해당 부문의 포스팅은 요기!

 

[Byte Order 바이트 오더] 빅엔디안(Big Endian)과 리틀엔디안(little endian) - 1편, 몰랑이말랑이블로그

안녕하세요~~!! 오늘도 시작되는 말랑이몰랑이 블로그 포스팅입니다~ ㅎㅎ 오늘은 네트워크나 통신쪽을 공부한다면 알고 있어야 할 Byte Order 의 빅엔디안과 리틀엔디안에 대한 개념을 완전하게 잡아보는 시간을..

jhnyang.tistory.com

 

결국 어떤 값을 메모리에 저장할 때 어떤 방식으로 저장하느냐에 따라 big endian과 little endian이 나눠지게 되는데요.

우리가 하나의 엔디안 방식만 사용한다면 문제가 없겠지만, 컴퓨터마다 어떤 데는 작은 엔디안을 쓰고 어떤데는 빅 엔디안을 쓰는 차이가 있기 때문에 문제가 발생하겠죠.

리틀 엔디안 빅엔디안 차이

오늘 포스팅을 진행하기 전 머릿속에 넣어져 있어야 할, 저장 방식 차이에 따른 그림입니다

다들 어떤 엔디안 방식을 사용하고 있는가?

일단, 엔디안 방식은 전형적으로 CPU에 의해 결정되는데요.

인텔CPU는 리틀 엔디안 방식을 사용하고, IBM, RISC기반의 컴퓨터들은 빅 엔디안 방식을 사용해요.

요렇게 목록을 정리된 표가 있길래 첨부!

리틀 엔디안 (Little Endian) VS 빅 엔디안 (Big Endian)

그런데, 어떤컴은 리틀방식을 쓰고 어떤 컴은 빅 엔디안을 쓰는 이유가 있겠죠?

각 방식의 장단점을 살펴봅시다.

 

1. 계산기의 가장 기본 덧셈!

컴퓨터는 결국 계산기라고 하죠. ㅎㅎ 저희 어떤 수를 덧셈할 때 어떻게 계산하는지 기억하시나요?

1234+5678을 예시로 들어봅시다.

이렇게 오른쪽에서부터 계산을 해줘요. 

그리고 10이상이면 carry가 생겨서 1을 다음 자리수에 올려주죠.

 

CPU회로상으로도 이와 동일한 로직으로 되어 있습니다.

즉 CPU도 오른쪽에서 왼쪽 순으로 계산을 해줍니다. carry도 똑같이 올려서 다음자리수에서 계산하게끔 회로적으로 구현되어 있어요.

위에 예시는 단순 숫자지만,, 컴퓨터니까 hex값으로 예시를 들어봅시다.

0x1234 + 0x5678이라고 생각할게요.

메모리상으로 구현을 해보면 각 엔디안의 경우 위처럼저장됩니다.

1234 수에서는 1이 가장 큰 자리수죠. 가장 큰 자리수가 메모리 맨 앞에 위치하는 것이 빅 엔디안이니까요 ㅎㅎ

간단하게 8bit 주소 체계로 예시

수치 계산시에는 리틀엔디안이 빅 엔디안보다 속도가 더 빠른데 두 숫자를 계산을 할 경우 가장낮은 자리수에 있는 숫자를 계산을 해보고서 자리 올림수가 있는지 없는지 판단하고 자리올림수와 다음 숫자를 계산하기 때문입니다. 결국 리틀엔디안으로 갔을때, 우리가 실질적으로 계산하는 방식과 동일해집니다.

리틀엔디안을 사용했을 때 수학적 연산이 쉽다는 장점이 있습니다. 반면 이는 빅엔디안의 단점이 되겠죠.

 

2. 타입형변환

리틀엔디안의 경우 어떤 타입의 시작 주소에 값이 들어간다는 특징이 있어요.

내가 int타입에 0x12를 저장하면 아래 이진수처럼 들어가겠죠?

근데 이 값을 int8_t 값으로 CAST하고 싶어! 그럼 리틀엔디안의 경우 데이터 시작 주소부터 8bit까지만 잘라주면 형변환이 됩니다. 즉 int8_t는 int의 시작점에 위치하게 되니까 쉽게 형변환 할 수 있어요. 다양한 크기의 타입들을 쉽게 읽어들일 수 있습니다.

 

반면 빅엔디안이라면, 앞의 0을 쭈우우욱 읽다가 끝까지 읽어서, 맨뒤 8bit를 취해야겠죠. 리틀엔디안이 타입을 읽거나 형변환 하는데에는 빠릅니다.

 

 

3. 숫자 비교 

반면 숫자 비교하는 데에는 빅엔디언이 빨라요.

빅엔디안은 큰자리수(most significant part)가 메모리 가장 처음에 위치!

숫자의 비교는 가장 큰 값이 들어가는 왼쪽부터 하게 되는데, 빅 엔디언은 수치를 앞에서부터 차곡차곡 스택에 집어넣는 반면 리틀 엔디언으로 하게 된다면 리틀 엔디언은 숫자 뒤에서부터 스택에 집어넣기 때문에 빅엔디언보다 속도가 느립니다.

 

4. 디버깅, 확인

프로그래머로써 숫자들을 확인하거나 메모리의 특정 범위내의 값들을 확인하고 싶을때 little endian이면 모든게 거꾸로 나와있으니까 매우 불편하겠죠. 반면 빅 엔디언은 사람이 읽는 순서와 동일하게 저장되니까 쉽게 쉽게 디버깅을 할 수 있다는 장점이 있습니다. 

 사람과 숫자를 읽고 쓰는 방법과 같기 때문에 디버깅 과정에서 메모리값을 보기 편합니다. 빅엔디언은 소프트웨어의 디버그가 편함!

 

4가지 엔디안별 특징을 알아봤습니다. 이 외에도 빅엔디안이 bit shifting 작업을 할땐 편하다던가 등의 다양한 특징들이 있지만, 엔디안의 특성을 정확하게 이해하고 있으면 파악하기 어렵지 않아요

 

다른 타입의 엔디언을 사용하면서 발생하는 문제

자 A라는 컴퓨터가 있고 B라는 서버가 있다고 합시다.

근데 A라는 컴퓨터에서 B라는 서버에게 데이터를 전송하려고 해요. 근데 A는 INTEL 프로세스를 사용하고 있어서 little endian방식이고 B 서버는 IBM제품의 big endian 방식이라고 합시다. 

엔디언 방식을 고려하지 않고 데이터를 보내게 되면, 나는 0x1234를 보냈는데, 상대방은 0x3412를 받는 불상사가 생겨요 ㅎㅎ

결과론적으로 엔디언 방식이 중요해지는건 네트워크! 데이터 전송을 할 때 엔디안 방식 차이에 주의해야 합니다. 서로 다른 데이터 저장 방식의 시스템끼리 통신하게 되면 전혀 엉뚱한 값을 주고받기 때문~~ 그래서 당연히, 규칙이 생겼죠.

 

NETWORK BYTE ORDER 네트워크 바이트 오더

그래서 규칙이 정해지게됐어요. 네트워크 상에 데이터를 전송할때는 네트워크바이트오더를 따라야 한다는 규칙!

네트워크 바이트 오더에선 빅 엔디안이 가장 흔한 포맷입니다. TCP, UPD, IPv4 IPv6과 같은 많은 프로토콜들이 데이터를 전송하는데 빅 엔디안 방식을 사용해요. 아래 자료는 마지막 라인을 보면 네트워크 바이트 오더는 빅엔디안 바이트 오더링 방식을 사용하기로 했다는걸 확인해볼 수 있습니다.

정리할겸 겸사겸사 보고 넘어가기

그래서 내 컴퓨터가 little endian이다~ 그러면 big endian으로 변환해줘야 합니다.

서버 입장에서도 어찌보면 마찬가지예요. 내가 받는 입장이라도, 서버라면 어떤 데이터가 들어올지에 대한 대비를 해놔야겠죠. 빅엔디안으로 보내~ 이래도 꼭 리틀엔디안으로 보내는 곳들이 있기 마련이니까요. ㅎㅎ 그래서 처리하기 전 체크를 해주고 다르다면 변환을 시켜줘야 합니다.

사실 소켓통신할 때 자주 사용되는 쓰거나 읽는 함수들의 경우에는 (write / read) 이미 내부적으로 엔디안 처리가 구현이 다 되어 있습니다. 그래서 소켓통신할때 포트랑 IP 데이터에 대한 변환만 챙겨주면 돼요. 

 

엔디안 변환 관련 함수들

이를 위해 아래와 같은 함수들이 있습니다. (C언어 기준) 

출처:http://blog.naver.com/wndrlf2003/70190031633

빅엔디안 변환 

htons (Host to Network Short) - short 메모리 값을 호스트 바이트 순서에서 네트워크 바이트 순서로  

htonl (Host to Network Long) - long 메모리 값을 호스트 바이트 순서에서 네트워크 바이트 순서로

리틀엔디안 변환

ntohs (Network to Host Short) - short 메모리 값을 네트워크 바이트 순서에서 호스트 바이트 순서로

ntohl (Network to Host Long) - long 메모리 값을 네트워크 바이트 순서에서 호스트 바이트 순서로

 

엔디안 변환하는 함수로 각각 short버전, long버전 2개씩 존재하는데,  short는 2바이트로 주로 포트데이터 변환할때 사용하고 long은 4byte로 ip주소 변환할때 사용합니다.

 

다음 포스팅에서는 내 컴퓨터가 리틀엔디안인지 바이트엔디안인지 확인하는 코드나,

위 관련 함수들에 대해 포스팅하는 시간을 갖도록해요. 

저도 배워가는 입장이라, 혹 틀린 부분이 있으면 가르쳐주시면 좋아요 :)

도움이 되었다면 공감, 댓글 or 광고보답은 어떤가요? 정보를 공유하는데 소소한 즐거움이 됩니다.

반응형