字节序

来源:互联网 发布:淘宝可以删除差评 编辑:程序博客网 时间:2024/05/29 14:56

简介

字节序分为两种,大端字节序和小端字节序。它们是多字节数据在内存中存储的两种方式,大端字节序:将高序字节存储在起始地址(低地址);小端字节序:将低序字节存储在起始地址。可以通过下面这个程序来查看主机字节序。

int main(int argc, char *argv[]){    union {        short n;        char c[sizeof(short)];    } un;    /* 01为高序字节,02位低序字节 */    un.n = 0x0102;    printf("%s: ", CPU_VENDOR_OS);    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("unknow\n");        }    } else {        printf("sizeof(short) = %d\n", sizeof(short));    }    return 0;}

由于这两种字节序都有系统使用,导致不同系统在网络上进行通信时,数据传输后的结果会有差异。但是网络协议必须指定一个大家都使用的(网络)字节序。网络协议使用大端字节序来传送这些多字节整数。

网络字节序

我们知道网络上的数据流是字节流,对于一个多字节数值,在进行网络传输的时候,先传递哪个字节?也就是说,当接收端收到第一个字节的时候,它是将这个字节作为高位还是低位来处理呢?
网络字节序定义:收到的第一个字节被当作高位看待,这就要求发送端发送的第一个字节应当是高位。而在发送端发送数据时,发送的第一个字节是该数字在内存中起始地址对应的字节。可见多字节数值在发送前,在内存中数值应该以大端法存放。
网络字节序说是大端字节序。

字节序转换函数

从理论上讲,具体实现可以按主机字节序存储套接字地址结构中的各个字段,等到需要在这些字段和协议首部相应字段移动时,再在主机字节序和网络字节序之间转换,让我们免于操心转换细节。然而由于历史的原因和POSIX规范的规定,套接字地址结构中的某些字段必须按照网络字节序进行维护。因此我们需要了解如何在主机字节序和网络字节序之间转换,这两种字节序之间的转换使用以下4个函数:

#include <netinet/in.h>/* 均返回网络字节序 */uint16_t htons(uint16_t host16bitvalue);uint32_t htonl(uint32_t host32bitvalue);/* 均返回主机字节序 */uint16_t htons(uint16_t host16bitvalue);uint32_t htonl(uint32_t host32bitvalue);

这些函数的名字中,h代表host,n代表network,s代表short(16),l代表long(32)。
注意
当使用这些函数时,不必关心主机字节序和网络字节序的真实值(或为大端,或为小端)。我们所要做的只是调用适当的函数在主机和网络字节序之间转换某个给定值。

0 0