/*
* 抄自《UNIX网络编程:卷1》, 稍作修改。
* 仅仅用于学习目的。学无止境,进步每一天。
*
* slickedit编辑。
*
* 254008829@qq.com
*
*/
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char **argv)
{
union {
short s;
char c[sizeof(short)];
} testObj;
testObj.s = 0x0102;
system("uname -a");
if (sizeof(short) == 2) {
if (testObj.c[0]==1 && testObj.c[1]==2) {
printf("Big-endian mode\n");
} else if (testObj.c[0]==2 && testObj.c[1]==1) {
printf("Little-endian mode!\n");
} else
printf("Unknown mode!\n");
} else
printf("This env sizeof(short) = %d\n", sizeof(short));
exit(0);
}
/*
* 运行结果:
wk@wk-laptop:~/OneProPerDay/0807_dyteorder/src$ ./byteorder
Linux wk-laptop 2.6.32-21-generic #32-Ubuntu SMP Fri Apr 16 08:10:02 UTC 2010 i686 GNU/Linux
Little-endian mode!
*/
上面结果说明在本机下面的字节序是小端模式的。不同的CPU厂商、操作系统版本中有的使用大端模式,有的使用小端模式。在网络传输过程中必须指定一个网络字节序,例如我们常说的端口号是一个16位的数字,以8000(0x1f40)为例。当小端字节序的环境指定端口号的时候,如果不转换成统一的字节序,以代码中的例子说明,则testObj.c[0]=0x40, testObj.c[1]=0x1f;当为大端字节序的时候,testObj.c[0]=0x1f,testObj.c[1]=0x40。上网的各个PC大小端什么情况都有,如果没有统一的规范,那么将乱套。
这里有一个概念,我们本机所用的字节序称之为“主机字节序”(host byte order)。
在Internet Protocol中,约定大端字节序来传递这些多字节的整数,这称之为网络字节序。
为使字节序统一,我们的代码里面需要在主机字节序和网络字节序中相互转换。有如下函数:
uint16_t htons(uint16_t host16bytes);
uint32_t htonl(uint32_t host32bytes);
uint16_t ntohs(uint16_t host16bytes);
uint32_t ntohl(uint32_t host32bytes);
在上述函数中,h代表host,s代表short,l代表long,n代表network。虽然现在64位cpu中long为64位,htonl和ntohl函数操作仍然是32位的值。