字节序监测

最近被人家问到关于字节序的问题,以前一般也没有怎么关心这方面的问题,不过怎么说这个也是一个基础的问题,今天就此就做个简单的记录:

程序之间的通信,其实就是发送数据流,字节(byte)被看作是数据的最小单位,一个字节中还包含8个比特(bit),这个是基础的计算机知识了,隐约中记得,这个在

我还没学习编程之前其实都已经明白这个东西了,貌似是高中有个数学课程里面提到过的,那时候记忆得比较清楚;

在一个32位的CPU中“字长”为32个bit,也就是4个byte。在这样的CPU中,总是以4字节对齐的方式来读取或写入内存,那么同样这4个字节的数据是以什么顺序保存在

内存中的呢?这就是所谓的字节序的问题了

每个数据都有“有效位”的概念,意思是“表示这个数据所用的字节”。例如一个32位整数,它的有效位就是4个字节。

举个例子,对于0x11223344来说,它的有效位从高到低便是11、22、33、44

对大字节序(big endian)(大端)来说,“最高有效位”落在低地址上

对小字节序(little endian)(小端)来说就是相反的方式,它把“最低有效位”放在低地址上

常用的CPU架构,如Intel,AMD的CPU使用的都是小字节序

那问题来了,我们如何对系统时大字节序还是小字节序进行检查呢?

第一种方法,使用强制类型转换的方式。C 语言在把占用2个字节的 short 变量强制转换为 char 之后,会把 short 变量的首地址赋给 char 变量,可以根据 char 变量的值判断系统字节序是 大端 还是 小端。

第二种方法,利用 联合类型 的特性。联合类型 共享同一段内存,首地址是相同的。

/*******************
 * 文件名:endian.c
 ******************/
#include <stdio.h>

/*********************************************************
 * 使用类型的强制转换实现little-endian与big-endian的判断
 *********************************************************
 * 返回值:
 *          1 表示是小端字节序。
 *          0 表示不是小端字节序。
 *********************************************************/
int is_little_endian_a(void)
{
    unsigned short flag = 0x4321;
    if(*(unsigned char*)&flag == 0x21)
        return 1;
    else
        return 0;
}

/*********************************************************************************
 * 利用联合的特点来判断little-endian与big-endian
 *********************************************************************************
 * 返回值:
 *          1   表示是小端字节序。
 *          0   表示是大端字节序。
 *          -1  表示不能使用这种方法确定字节序。比如有的机器的 short 长度不是 2 。
 ********************************************************************************/
int is_little_endian_b(void)
{
    union endian_un{
        short var;
        char bits[sizeof(short)];
    };

    union endian_un flag;
    flag.var=0x0102;

    //判断低位和高位的存储内容,确定是何种方式
    if(sizeof(short) == 2){
        if(flag.bits[0] == 1 && flag.bits[1] == 2)
            return 0;
        else if(flag.bits[0] == 2 && flag.bits[1] == 1)
            return 1;
        else
            return -1;
    } 

    return -1;
}

int main(void)
{
    int type = 0;

    type = is_little_endian_a();
    if (1 == type)
        printf("judged by first method, little-endian\n");
    else if (0 == type)
        printf("judged by first method, big-endian\n");

    type = is_little_endian_b();
    if (1 == type)
        printf("judged by second method, little-endian\n");
    else if (0 == type)
        printf("judged by second method, big-endian\n");
    else
        printf("can‘t judge it\n");

    return 0;
}

Mac平台上面进行测试,效果如下:

adeMacBook-Pro:lua_dev apple$ ./endian
judged by first method, little-endian
judged by second method, little-endian

应用:

主要在多台计算机之间数据的传递上面,如何去编排字节顺序,多用于分布式网络系统的设计上面;

时间: 2024-12-29 06:48:51

字节序监测的相关文章

字节序转换与结构体位域(bit field)值的读取 Part 2 - 深入理解字节序和结构体位域存储方式

上一篇文章讲解了带位域的结构体,在从大端机(Big Endian)传输到小端机(Little Endian)后如何解析位域值.下面继续深入详解字节序,以及位域存储的方式. (1) 我们知道,存储数字时,对小端机而言,数字的低位,存在低地址,高位存在高地址.大端机正相反. (2) 读取的方式,也是一样的.对于小端机,读出的低地址位作为数字的低位. (3) 此外Big-Endian/Little-Endian存储顺序,不仅仅针对字节,还针对字节内的比特位.对于小端机而言,字节内的8个比特,低地址端比

字节序

1.什么是字节序 字节序是指多字节数据在计算机内存中存储或者网络传输时各字节的存储顺序.由于数据在内存中存储的顺序与操作系统有关,因此字节在主机中的存储顺序通常称为主机序:而数据在网络中的存储顺序则称为网络序. 常见的字节序有:大端字节序(Big endian)与小端字节序(Little endian). 主机序依CPU而定:Intel x86为Little endian,Motorola680x则是Big endian. 网络序与CPU无关都是Big endian, 这是因为统一字节序有利于数

【Linux 网络编程】字节序和地址装换

(3)字节序    <1>大端字节序        最高的有效位存储于最低内存地址处,最低有效位存储于最高内存地址处.    <2>小端字节序        最高的有效位存储于最高内存地址处,最低有效位存储于最低内存地址处.  保存0x12345678       ----------------->内存地址增长的方向        12 34 56 78 大端字节序        78 56 34 12 小端字节序    <3>主机字节序        不同的主

c# 主机和网络字节序的转换 关于网络字节序和主机字节序的转换

最近使用C#进行网络开发,需要处理ISO8583报文,由于其中有些域是数值型的,于是在传输的时候涉及到了字节序的转换. 字节顺序是指占内存多于一个字节类型的数据在内存中的存放顺序,通常有两种字节顺序,根据他们所处的位置我们分别称为主机节序和网络字节序. 通常我们认为网络字节序为标准顺序,封包的时候,将主机字节序转换为网络字节序,拆包的时候要将网络字节序转换为主机字节序. 原以为还要自己写函数,其实网络库已经提供了. 主机到网络:short/int/long IPAddress.HostToNet

小端字节序与大端字节序

端模式分为:小端字节序和大端字节序,也就是字节在内存中的顺序. 小端字节序:低字节存于内存低地址:高字节存于内存高地址.如一个long型数据0x12345678 0x0029f458 0x78 0x0029f459 0x56 0x0029f45a 0x34 0x0029f45b 0x12 在以上数据存放于内存中的表现形式中,0x0029f458 < 0x0029f459 < 0x0029f45a < 0x0029f45b, 可以知道内存的地址是由低到高的顺序:而数据的字节也是由低到高的,

实现两个字节序的交换

实现两个字节序的交换例如:300=0X012C,交换之后为0X2C01 1 /******************************************************************************* 2 * Function Name : exchangeBytes 3 * Description : 模拟的htons 或者 ntohs,如果系统支字节序更改可直接替换成系统函数 4 * Input : value 5 * Output : None 6 *

内存对齐,大端字节 &nbsp; 序小端字节序验证

空结构体:对于空结构体,就是只有结构体这个模子,但里面却没有元素的结构体. 例: typedef struct student { }std: 这种空结构体的模子占一个字节,sizeof(std)=1. 柔性数组: 结构体中最后一个元素可以是一个大小未知的数组,称作柔性数组成员,规定柔性数组前面至少有一个元素. typedef struct student { int i; char arr[];     //柔性数组成员 }std: sizeof(std)=4; sizeof求取该结构体大小是

对于字节序小端和大端的思考

最近公司处理器要换核,由小端处理器ARM换成大端处理器POWERPC,bootloader以及kernel的移植工作交给了我,这是一个很有挑战的工作,自己也非常兴奋. 如此一来,当今主流的嵌入式处理器(MIPS ARM PPC)也都算接触过啦. 这几天开始动手做移植,首先要解决的是大小端的差异,进过学习思考,感觉大小端还是很有研究的必要,自己的思考总结记录在此,与大家分享,以备后用. 从网上可以查到的大小端的解释,小端是低端数据存放在低端地址,大端是高端数据存在低端地址.大小端真的就这么简单吗,

1.socket编程:socket编程,网络字节序,函数介绍,IP地址转换函数,sockaddr数据结构,网络套接字函数,socket相关函数,TCP server和client

 1  Socket编程 socket这个词可以表示很多概念: 在TCP/IP协议中,"IP地址+TCP或UDP端口号"唯一标识网络通讯中的一个进程,"IP 地址+端口号"就称为socket. 在TCP协议中,建立连接的两个进程各自有一个socket来标识,那么这两个socket组成的socket pair就唯一标识一个连接.socket本身有"插座"的意思,因此用来描述网络连 接的一对一关系. TCP/IP协议最早在BSD UNIX上实现,