网络字节序
以一个4字节unsigned int 来说, 比如0xFF00FF00, 他的二进制表示是 11111111 00000000 11111111 00000000, 我们说左侧是高位, 右侧是地位
在说明网络字节序之前, 我们需要弄明白大端字节序和小端字节序
小端字节序:
假设地址从左到右一次增大, 则如果把一个数的高位字节存储在最右侧, 低位字节存储在最左侧, 比如0xF00FF00F 按照小端字节序存储就变成了0x0FF00FF0, 注意这里是按照字节为单位的, 不是位,
大端字节序:
与小端字节序相反, 把高位字节存储在最左侧, 地位字节存储在右侧, 比如0xF00FF00F的大端字节序就是0xF00FF00F, 很明显大端字节序更符合人的思维习惯
网络字节序:
其实网络字节序就是大端字节序, 通常在网络编程中, 当构造一个sockaddr_in时, 我们需要把端口号(sin_port)和地址(sin_addr)以大端字节序来存储, 这是因为, 有些系统的本机字节序是小端字节序, 有些则是大端字节序, 为了保证传送顺序的一致性, 所以网际协议使用大端字节序来传送数据。我们可以用htons函数把一个short整数从本机字节序转为大端字节序, 用inet_pton得到ip地址的大端字节序
这里给出一个本机字节序到网络字节序的转换的简单实现:
1 /*返回本机字节序, true表示大端字节序, false表示小端字节序*/ 2 bool check_hbo() 3 { 4 union { 5 short i; 6 bool c[sizeof(i)]; 7 } un; 8 un.i = 0xFF00; 9 return un.c[0]; 10 } 11 12 uint16_t htons(uint16_t host16bitvalue) 13 { 14 if(check_hbo()) 15 return host16bitvalue; 16 int i = 0, j = sizeof(host16bitvalue) - 1; 17 union { 18 uint16_t i; 19 char c[sizeof(host16bitvalue)]; 20 } un; 21 un.i = host16bitvalue; 22 for(;i < j; ++i, --j) 23 { 24 un.c[i] ^= un.c[j]; 25 un.c[j] ^= un.c[i]; 26 un.c[i] ^= un.c[j]; 27 } 28 return un.i; 29 }