[C]리틀엔디안(Little Endian)과 빅엔디안(Big Endian), 그리고 상호 변환 함수
Posted 2007/08/22 12:01엔디안[Endian]
단어를 형성하는 2진 바이트에서 저장하는 바이트의 순서를 나타내는 방법.
-네이버 백과사전 펌
나름 백과사전에서 퍼오긴 했지만 너무 어렵다..-_-;;
Endian은 메모리에 데이터를 배치하는 방법을 말하는 것인데, Endian에는 Little Endian과 Big Endian이 있다. 이 두개의 차이점을 예를 통해서 쉽게 알 수 있다.
Example:
어떤 값이 있다고 하자. 16진수로 0x82D4라는 값이 있다면,
Little Endian : 0xD482
Big Endian : 0x82D4
두 방식의 차이점은 이거밖에 없다. 단지 네트워크상에서의 표준은 Big Endian을 따른다는 점이다. 아참, 보통 인텔의 Pentium에서는 Little Endian을 쓴다는것! 그래서 네트워크로 데이터를 교환할때는 Little Endian과 Big Endian을 서로 변환해야 할 필요가 생긴다.
그렇다면 [C]에서는 어떻게 변환할 수 있을까?
** 이 곳의 모든 함수는 winsock2.h를 Include해야합니다.
** 필자의 경우에 Host는 Little Endian을 사용한다.
** 왼쪽 함수는 Original함수, 오른쪽함수는 확장함수이다. 확장함수의 이점은 함수가 소켓을 인수로 받기때문에, 소켓이 사용하는 네트워크에 맞게 변환해준다는 이점이 있다. 결과는 동일하다.
htons(Host TO Network Short), WSAHtons
이 함수는 unsigned short형식의 자료를 호스트에서 사용하는 엔디안에서 네트워크가 사용하는 엔디안(Big Endian)으로 변환해준다. 주로 포트번호 변환에 사용된다.
void main() //htons 버전
{
unsigned short ex=0x1234;
printf("Before : 0x%04x \n", ex);
ex = htons(ex);
printf("After : 0x%04x \n", ex);
}
void main() //WSAHtons 버전
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2,2), &wsaData);
SOCKET sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
unsigned short before=0x1234, after;
printf("Before : 0x%04x \n", before);
WSAHtons(sock, before, &after);
printf("After : 0x%04x \n", after);
closesocket(sock);
WSACleanup();
}
(결과)
Before : 0x1234
After : 0x3412
ntohs(Network TO Host Short), WSANtohs
이 함수는 unsigned short형식의 자료를 네트워크가 사용하는 엔디안(Big Endian)에서 호스트에서 사용하는 엔디안으로 변환해준다. 주로 포트번호 변환에 사용된다.
void main() //ntohs버전
{
unsigned short ex=0x1234;
printf("Before : 0x%04x \n", ex);
ex = ntohs(ex);
printf("After : 0x%04x \n", ex);
}
void main() //WSANtohs 버전
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2,2), &wsaData);
SOCKET sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
unsigned short before=0x1234, after;
printf("Before : 0x%04x \n", before);
WSANtohs(sock, before, &after);
printf("After : 0x%04x \n", after);
closesocket(sock);
WSACleanup();
}
(결과)
Before : 0x1234
After : 0x3412
htonl(Host TO Network Long), WSAHtonl
이 함수는 unsigned long형식 또는 DWORD형식의 자료를 호스트에서 사용하는 엔디안에서 네트워크가 사용하는 엔디안(Big Endian)으로 변환해준다. 주로 IP주소 변환에 사용된다.
void main() //htonl버전
{
unsigned long ex=0x12345678;
printf("Before : 0x%08x \n", ex);
ex = ntohl(ex);
printf("After : 0x%08x \n", ex);
}
void main() //WSAHtonl 버전
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2,2), &wsaData);
SOCKET sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
unsigned long before=0x12345678, after;
printf("Before : 0x%08x \n", before);
WSAHtonl(sock, before, &after);
printf("After : 0x%08x \n", after);
closesocket(sock);
WSACleanup();
}
(결과)
Before : 0x12345678
After : 0x78563412
ntohl(Network TO Host Long), WSANtohl
이 함수는 unsigned long형식 또는 DWORD형식의 자료를 네트워크가 사용하는 엔디안(Big Endian)에서 호스트에서 사용하는 엔디안으로 변환해준다. 주로 IP주소 변환에 사용된다.
void main() //ntohl버전
{
DWORD ex=0x12345678;
printf("Before : 0x%08x \n", ex);
ex = ntohl(ex);
printf("After : 0x%08x \n", ex);
}
void main() //WSANtohl 버전
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2,2), &wsaData);
SOCKET sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
DWORD before=0x12345678, after;
printf("Before : 0x%08x \n", before);
WSAHtons(sock, before, &after);
printf("After : 0x%08x \n", after);
closesocket(sock);
WSACleanup();
}
(결과)
Before : 0x12345678
After : 0x78563412
** 참고, 도트 표기법으로된 IP주소를 4바이트 IP주소(IPv4)로 변환하기.
inet_addr
IPv4로 변환할때, 결과값은 네트워크 바이트오더에 따릅니다. 즉, inet_addr의 결과를 htonl함수를 사용하여 따로 변환할 필요가 없다는 말이 되겠습니다.
void main()
{
char MyIP[] = "211.179.80.239";
printf("IPv4 : 0x%x\n", inet_addr(MyIP));
}
(결과)
IPv4 : 0xef50b3d3
(결과해석)
결과값인 0xef50b3d3은 바로 해석하면 239.80.179.211이 됩니다. 즉, 네트워크 바이트오더입니다.
inet_ntoa
inet_addr의 반대기능을 하는 함수. 이것도 네트워크 바이트오더에 따르는 IPv4를 host에서 사용하는 바이트오더로 자동 변환 후 보여주기 때문에 따로 형식변환을 할 필요가 없습니다.
void main()
{
in_addr MyIP;
MyIP.S_un.S_addr = 0xef50b3d3;
printf("IP : %s\n", inet_ntoa(MyIP));
}
(결과)
IP : 211.179.80.239
(결과해석)
입력값인 0xef50b3d3을 바로 해석하면 239.80.179.211이 됩니다. 즉, 결과값은 호스트 바이트 오더를 따르는것을 알 수 있습니다.
** 이 글의 저작권은 모두 저자에게 있습니다.
수정, 배포시 저작권을 표시해주시기 바랍니다.
** 오타, 잘못된 내용이 있으면 적극적으로 알려주시기 바랍니다 :)
** 질문사항 또한 적극적으로 받겠습니다.
Copyright (c) NEWMS 2007 All right Reserved.
'눈으로 보이는 > 배움' 카테고리의 다른 글
| Newms's Basic Assembly for Reverse Engineering #3 (0) | 2007/08/24 |
|---|---|
| Window State Messages Constants (0) | 2007/08/22 |
| [C]리틀엔디안(Little Endian)과 빅엔디안(Big Endian), 그리고 상호 변환 함수 (0) | 2007/08/22 |
| [C++]Template로 자료형에 대한 다형성 지원! (2) | 2007/08/21 |
| Winsock 프로그래밍을 위한 준비작업! (0) | 2007/08/21 |
| Newms's Basic Assembly for Reverse Engineering #2 (0) | 2007/08/21 |
- Filed under : 눈으로 보이는/배움
- Tag : Big Endian, endian, Little Endian, Network, TCP/IP, 네트워크, 바이트오더
- Comment Trackback