본문 바로가기

프로그래밍/Network

마샬링


서로 다른 엔디안을 사용하는 시스템간에 통신을 위해서는 엔디안을 한쪽으로 맞춰야 한다.
이런 문제를 해결하는 것을 마샬링(Marshalling) 또는 바이트 순서(byte order)를 맞춘다고 한다.

일반적으로 마샬링을 할 때는 네트워크 바이트 순서로 변환을 하는데,
네트워크 바이트 순서는 빅 엔디안 방식의 바이트 순서이다.
네트워크 프로그래밍에서는 마샬리을 위해 다음과 같은 바이트 스왑 함수를 제공한다.

unsigned long htonl ( unsigned long ); //호스트에서 네트워크로
unsigned short htons ( unsigned short ); //호스트에서 네트워크로
unsigned long ntohl ( unsigned long ); //네트워크에서 호스트로
unsigned short ntohs ( unsigned short );  //네트워크에서 호스트로

마샬링이 필요한 경우에는 클라이언트가 서버쪽 바이트 순서에 맞추어야 한다.

int main() {
	unsigned char Little_Endian_data[6];
	unsigned char Big_Endian_data[6];
	unsigned short U_short = 123, Netshort;
	unsigned int U_int = 456, Netint;

	printf("Little endian U_short:%d U_int:%d\n\n", U_short, U_int);

	U_Netshort = htons(U_short);
	U_Netint = htonl(U_int);
	printf("Big endian U_Netshort:%d U_Netint:%d\n",
		U_Netshort, U_Netint);

	memcpy(&Little_Endian_data[0], &U_short, 2);
	memcpy(&Little_Endian_data[2], &U_int, 4);

	Big_Endian_data[0] = Little_Endian_data[1];
	Big_Endian_data[1] = Little_Endian_data[0];

	Big_Endian_data[2] = Little_Endian_data[5];
	Big_Endian_data[3] = Little_Endian_data[4];
	Big_Endian_data[4] = Little_Endian_data[3];
	Big_Endian_data[5] = Little_Endian_data[2];

	memcpy(&U_Netshort, &Big_Endian_data[0], 2);
	memcpy(&U_Netint, &Big_Endian_data[2], 4);
	printf("Big endian U_Netshort:%d U_Netint:%d\n",
		U_Netshort, U_Netint);
}

실행해보면 htons, htonl 함수를 사용하여 변환한 값과
직접 바이트 순서를 바꾼 값이 같게 나오는 것을 확인할 수 있다.