字节排序函数

考虑一个16位的整数,它由2个字节组成。在内存中,存储这16位整数的方法有两种:

  1. 将底序字节存储在起始地址,这称为小端(little-endian)字节序;
  2. 将高序字节存储在起始地址,称为大端(big-endian)字节序。

可以用C代码验证你的机器是哪种存储方式:

/* file: lib/byteorder.c */
#include <stdio.h>

int main(int argc, char const *argv[])
{
    
    union 
    {
        short s;
        char c[sizeof(short)];
    } un;

    un.s = 0x0102;

    if(sizeof(short) == 2){
        if(un.c[0] == 1 && un.c[1] == 2)
            printf("big-endian\n");
        else if(un.c[0] == 2 && un.c[1] == 1)
            printf("little-endian\n");
        else
            printf("unknown!\n");
    }
    else
        printf("The short size is not 2!\n");
    
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

由于历史的原因和POSIX规范的规定,套接字地址结构中的某些字段必须按照网络字节序进行维护,因此我们要关注如何在主机字节序和网络字节序之间互相转换。这两种字节序之间的转换可以使用以下四个函数。

#include <netinet/in.h>

/* 返回网络字节序 */
u_int16_t htons(u_int16_t host16bitvalue);
u_int32_t htonl(u_int32_t host32bitvalue);

/* 返回主机字节序 */
u_int16_t ntohs(u_int16_t net16bitvalue);
u_int32_t ntohl(u_int32_t net32bitvalue);

1
2
3
4
5
6
7
8
9
10

在这些字节序函数中,h代表hostn 代表 networks 代表 shortl代表long

当使用这些函数时,我们不需要关心主机字节序和网络字节序的到底是什么,只需要调用适当的调整函数在主机和网络之间转换某个值。在那些和网际协议所用字节序(大端)相同的系统中,这四个函数通常被定义为空宏。

最近更新: 12/23/2018, 3:55:43 PM