TCP/IP 프로토콜이 따르는 다중바이트 정수 표현 방식을 네트워크 바이트 순서(network byte order)라고도 한다. 양단에 있는 컴퓨터가 리틀-엔디안 방식을 따르더라도, 전송하는 쪽 컴퓨터는 다중바이트 정수를 네트워크 바이트 순서로 변환한 후 전송한다. 그러면 수신하는 쪽 컴퓨터는 네트워크 바이트 순서인 정수를 받아서 리틀-엔디안으로 변환한다.
예를 들어, IP 주소가 192.0.1.2인 컴퓨터와 TCP 소켓으로 연결하려고 한다. IPv4(Internet Protocol version 4)는 32비트 정수를 사용하여 네트워크 호스트를 식별하므로 IP 주소가 192.0.1.2인 컴퓨터를 찾으려면 이 IP 주소를 32비트 정수로 변환해야 한다.
여기서 80x86 기반 PC가 스팍 기반 서버와 인터넷으로 통신한다고 가정하자. 엔디안 방식을 고려하지 않는다면, 80x86 프로세서는 192.0.1.2를 리틀 엔디안 정수 0x020100C0로 변환하여 02 01 00 C0 순서로 전송한다. 그러면 스팍 CPU는 02 01 00 C0 순서로 들어오는 바이트를 빅 엔디안 정수 0x020100c0로 인식하여 2.1.0.192라는 엉뚱한 주소를 얻는다.
TCP/IP 스택이 리틀 엔디안 프로세서에서 돌아간다면 계층 헤더 내 모든 다중바이트 값을 실행 중에 재정렬해야 한다. TCP/IP 스택이 빅 엔디안 프로세서에서 돌아간다면 걱정할 필요가 없다. 엔디안 방식에 상관 없이 스택을 돌리려면 재정렬 여부를 (보통 컴파일 시에) 결정해야 한다.
이러한 변환을 돕고자 소켓은 자료를 호스트 순서에서 네트워크 바이트 순서로 혹은 네트워크 바이트 순서에서 호스트 순서로 변환하는 매크로를 제공한다.
- htons()
- 16비트 unsigned 값을 프로세서 순서에서 네트워크 순서로 변환한다. 매크로 이름은 "host to network short"를 줄인 말이다.
- htonl()
- 32비트 unsigned 값을 프로세서 순서에서 네트워크 순서로 변환한다. 매크로 이름은 "host to network long"을 줄인 말이다.
- ntohs()
- 16비트 unsigned 값을 네트워크 순서에서 프로세서 순서로 변환한다. 매크로 이름은 "network to host short"를 줄인 말이다.
- ntohl()
- 32비트 unsigned 값을 네트워크 순서에서 프로세서 순서로 변환한다. 매크로 이름은 "network to host long"을 줄인 말이다.
Listing 7에 있는 C 프로그램을 살펴보자.
Listing 7. 예제 C 프로그램
#include <stdio.h>
main() {
int i;
long x = 0x112A380; /* 테스트 대상 값 */
unsigned char *ptr = (char *) &x; /* 바이트 포인터 */
/* 호스트 바이트 순서로 값을 출력 */
printf("x in hex: %x\n", x);
printf("x by bytes: ");
for (i=0; i < sizeof(long); i++)
printf("%x\t", ptr[i]);
printf("\n"); /* 네트워크 바이트 순서로 값을 출력 */ x = htonl(x);
printf("\nAfter htonl()\n");
printf("x in hex: %x\n", x);
printf("x by bytes: ");
for (i=0; i < sizeof(long); i++)
printf("%x\t", ptr[i]);
printf("\n");
}
|
이 프로그램은 값이 16진수 112A380인 long 변수 x가 저장된 방식을 살펴본다.
위 프로그램을 리틀 엔디안 프로세서에서 실행하면 Listing 8과 같은 결과를 얻는다.
Listing 8. 리틀 엔디안 프로세서에서 실행한 결과
x in hex: 112a380
x by bytes: 80 a3 12 1
After htonl()
x in hex: 80a31201
x by bytes: 1 12 a3 80
|
변 수 x에서 개별 바이트를 살펴보면 최하위 바이트 0x80이 최하위 주소에 놓인다. 그러나 htonl( )을 호출하여 네트워크 바이트 순서로 변환하면 최상위 바이트 0x1이 최하위 주소에 놓인다. 물론 바이트 순서를 변환한 후 x 값을 출력하면 전혀 의미 없는 숫자를 얻는다.
Listing 9는 같은 프로그램을 빅 엔디안 프로세서에서 실행한 결과다.
Listing 9. 빅 엔디안 프로세서에서 실행한 결과
x in hex: 112a380
x by bytes: 1 12 a3 80
After htonl()
x in hex: 112a380
x by bytes: 1 12 a3 80
|
여기서는 최상위 바이트 0x1이 최하위 주소에 놓인다. htonl( )을 호출하여 네트워크 바이트 순서로 변환해도 x 값은 변하지 않는다. 네트워크 바이트 순서가 이미 빅 엔디안 방식이기 때문이다.
출처 : http://www.cyworld.com/pimpthesun/1262789