IT정보공유/C#

C# TCP Socket 통신시 빅엔디안과 리틀엔디안 변환방법

알지오™ 2021. 11. 24.

TCP Socket 통신을 하다보면 발생할 수 있는 리틀엔디안, 빅엔디안 변환 방법에 관한 내용을 정리해봤습니다.

리틀엔디언? 빅엔디언? 무슨 차이일까?

일단 조금이나마 쉽게 설명해보자면 데이터의 정렬방법이라고 할 수 있는데
4Byte integer 변수인 i의 값을 33이라고 했을 때, HEX로 표기하면 다음 표와 같습니다.

 

구분 HEX
리틀엔디안(Little-Endian) 0x33 0x00 0x00 0x00
빅엔디안(Big-Endian) 0x00 0x00 0x00 0x33

 

이렇게 차이가 나게 데이터가 메모리에 정렬이 되는것이죠. 
(저장방식의 차이라고 생각해도됩니다. 실제 이런 데이터들을 파일로 저장할때도 위와 같은 차이로 저장되니까요.)

 

 

C#은 기본적으로 리틀엔디안을 사용하고, 인텔 x86 계열은 리틀엔디언을 사용합니다.

주로 윈도우를 사용하는 인텔, AMD등의 x86계열의 CPU는 리틀엔디언을 사용하는데, 
서버군들의 칩셋은 빅엔디안을 사용했기 때문에 두 방식간의 데이터를 소켓 통신으로 주고받을 경우에
이 정렬방법 차이 때문에 엉뚱한 값으로 해석하는 일이 벌어집니다.
그러다 보니 리틀엔디안 시스템과, 빅엔디안 시스템이 서로 값을 다르게 해석할 수 밖에 없고, 
이런 문제를 해결하기 위해 네트워크오더링, 또는 바이트오더링이라고 하는 리틀엔디언, 빅엔디언을 맞춰주는 것이 필요합니다.

 

C# 프로그래밍을 할 경우, 기본적인 데이터 정렬은 리틀엔디언입니다. (자바는 빅엔디언이라고 합니다.)
이를 빅엔디안으로 바꾸기 위해서는 IPAddress.HostToNetworkOrder(), IPAddress.NetworkToHostOrder() 를 이용해야합니다.

 

윈도우 <-> 유닉스 통신시 주로 발생

C#에서 이기종 서버로 데이터를 전송할 때, IPAddress.HostToNetworkOrder()로 빅엔디안으로 데이터정렬.
C#에서 이기종 서버로 부터 수신 받은 데이터를 다시 변환할때 IPAddress.NetworkToHostOrder()를 사용합니다.

 

참고로 TCP/IP 소켓통신 프로그래밍 개발시에 주로 발생 하는 문제가
리틀엔디안, 빅엔디안은 int, short, long, double 등과 같은 정수,실수 등의 값을 문자열이 아닌 byte배열등으로 주고받을때 입니다.

그래서 데이터를 보내는 입장에서는 아래 샘플 코드 처럼 바이트오더링(HostToNetworkOrder 함수 이용)을 해서 보내야 합니다.

 

//
/* SendDataAll 이라는 바이트배열에 short형 Dong 변수를 네트워크오더 함수를 통해 빅엔디안으로 변환 */

Array.Copy(BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)Dong)), 0, SendDataAll, idx, 2);

//

 

소켓통신시 주로 검색하게 되는 키워드들이 리틀엔디안, 빅엔디안, 바이트오더링, 네트워크오더 등인데,
모두 이와 같은 데이터정렬 방법에 관한 것으로 생각하셔도 무방합니다.

댓글

💲 추천 글