百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术流 > 正文

大小端(网络序--大端;主机序--一般是小端)

citgpt 2024-10-22 16:08 8 浏览 0 评论

什么是大小端

  • 首先明白字节序,字节序指占内存超过1个字节类型的数据在内存中存放顺序,通常有大端和小端两种顺序:

  • 大小端是内存存储字节的两种方式,一个是大端存储,一个是小端存储。

  • 网络字节序使用的是大端方式,大部分计算机使用的是小端模式。

  • 采用大小模式对数据端进行存放的主要区别在于存放的字节顺序,大端方式将高位存放在低地址,小端方式将高位存放在高地址。

  • 采用大端方式进行数据存放符合人类的正常思维,而采用小端方式进行数据存放利于计算机处理。

image

  • 大端存储:指低字节数据存放在内存地址,高字节数据存放在高地址处

  • 小端存储:指低字节数据存放在高地址处,高字节数据存放在内存地址处。

大小端的意义

主机序、网络序

1、主机序(大部分计算机采用 小端模式)

不同的CPU处理数据有不同的字节序类型,将一台设备的字节序类型称作为主机序

2、网络序(大端模式)

网络上以字节流的方式传输数据,在传输过程中的字节序类型称为网络序。与其他具体设备的CPU/OS类型无关,保证了在不同设备间传输时能被正确解析。

 网络序固定采用大端模式,所以在大端设备中主机序和网络序是相同不需要转换

如何确定大小端

使用联合体(共同体)来检查

联合体

在C语言中,联合体也被称为共用体,它的关键字是union。
定义一个联合类型的一般形式为:

union 联合名
{
	成员表
};

联合体占用的字节数与其成员中最大数据类型占用的字节数相等,例如:

union Un{	int a;	char b;
}un;

该联合体中成员a是int类型占四个字节,成员b是char类型占一个字节,所以该联合体Un在内存中占四个字节,并且联合体中的成员能够公用一个内存空间,内存可以这样表示:
image
由于联合体的特性,通过截取b,即可知道字节序的存放方式,即可知道是大端机还是小端机。

代码检测

#include <stdio.h>int Check_sys(){    union Un
    {        char c;        int i;
    }un;
    un.i = 1;    //如果是大端机则是0x1000 0000 0000 0000
    //如果是小端机则是0x0000 0000 0000 0001
    return un.c;
}int main(){    int ret=Check_sys();//由于联合体的特性,大端机ret=0(0000),小端机ret=1(0001)
    if (1 == ret)
    {        printf("当前模式为小端存储\n");
    }    else
    {        printf("当前模式为大端存储\n");
    }    return 0;
}

输出结果:
image

使用指针检测

一个 int 的指针每次偏移的是4个字节,而一个 char 类型的指针每次偏移的是一个字节,那么就可以类似于上面联合体的方式截取内存中的字节来进行大小端的判断

int Check_sys(){	int a = 1;	char* p = (char*)&a;	return *p;  //大端返回0,小端返回1}int main(){	int ret = Check_sys();	if (1 == ret)
	{		printf("当前模式为小端存储\n");
	}	else
	{		printf("当前模式为大端存储\n");
	}	return 0;
}
检测结果
![image](https://img2023.cnblogs.com/blog/3033909/202308/3033909-20230814002037259-546590832.png)

什么时候需要转换大端与小端

  • 内存存储以Byte为单位,当涉及一个Byte的变量存储时是没有区分的

  • c语言中内置的数据类型有int、double、short等多字节类型,存储该类型时将有两种方式,即上述的大端(低地址高位)与小端(低地址低位),这类的变量在由host1发送至host2时,需要进行大小端转换,即host1发往网络进行hton,host2接收时进行网络序转主机序。

1、两者转换

为实现不同设备间的通讯,数据能够被正确的解析,需要进行主机序与网络序之间的转换。

相同字节序的设备进行网络通信时无需字节转换,反正必须进行字节序转换

2、转换函数:

字节序转换函数会根据当前平台存储模式做响应正确的转换,如果当前平台是大端,则直接返回不进行转换,如果当前平台是小端,会将接收得到的网路字节序进行转换

这要求硬件工程师在硬件设计中注意端模式的转换。

3、如果场景是host1发送tcp报文报文至host2,但是host2接收时并未进行网络序转主机序,那么将会出现什么情况?

报文字节流是网络字节序,host2接收后并未进行主机序转换(仍以大端存储),此时如果进行报文解析(以小端方式解析),解析出来的报文将会出错,以以太帧类型为例

uint8 *raw_buf = m_buf; //指向报文字节流,未进行大小端转换
uint16 eth_type = (uint16 *)(raw_buf + 12); //eth_type存储报文类型,未进行大小端转换

以太帧类型网络字节序为大端0x0800

当原封不动到达主机端,eth_type由强转获取,即内存存储的仍为0x08 0x00

(gdb) x/2xb ð_type0x7fffffffe50e: 0x08 0x00

但是,需要注意的是此时host2将以小端方式解析该变量,即内存0x7fffffffe50e: 0x08 0x00将解析为0x0008

(gdb) p/x eth_type$3 = 0x8

总结

  • 大端和小端只是两种存储方式,但是无论如何存储,只要按照各自的解析方式,解析出来的含义是一致的就OK。例如host1为小端存储,host2为大端存储,但是两个计算机中运行的c程序中变量eth_type永远都是0x0800这种我们熟知含义的协议号。所以程序员不用过分关注大小端。

  • 不进行大小端转换,将会导致原来大端模式存储的数据,却以小端存储方式来解读,必然会导致错误。


相关推荐

js中arguments详解

一、简介了解arguments这个对象之前先来认识一下javascript的一些功能:其实Javascript并没有重载函数的功能,但是Arguments对象能够模拟重载。Javascrip中每个函数...

firewall-cmd 常用命令

目录firewalldzone说明firewallzone内容说明firewall-cmd常用参数firewall-cmd常用命令常用命令 回到顶部firewalldzone...

epel-release 是什么

EPEL-release(ExtraPackagesforEnterpriseLinux)是一个软件仓库,它为企业级Linux发行版(如CentOS、RHEL等)提供额外的软件包。以下是关于E...

FullGC详解  什么是 JVM 的 GC
FullGC详解 什么是 JVM 的 GC

前言:背景:一、什么是JVM的GC?JVM(JavaVirtualMachine)。JVM是Java程序的虚拟机,是一种实现Java语言的解...

2024-10-26 08:50 citgpt

使用Spire.Doc组件利用模板导出Word文档
  • 使用Spire.Doc组件利用模板导出Word文档
  • 使用Spire.Doc组件利用模板导出Word文档
  • 使用Spire.Doc组件利用模板导出Word文档
  • 使用Spire.Doc组件利用模板导出Word文档
跨域(CrossOrigin)

1.介绍  1)跨域问题:跨域问题是在网络中,当一个网络的运行脚本(通常时JavaScript)试图访问另一个网络的资源时,如果这两个网络的端口、协议和域名不一致时就会出现跨域问题。    通俗讲...

微服务架构和分布式架构的区别

1、含义不同微服务架构:微服务架构风格是一种将一个单一应用程序开发为一组小型服务的方法,每个服务运行在自己的进程中,服务间通信采用轻量级通信机制(通常用HTTP资源API)。这些服务围绕业务能力构建并...

深入理解与应用CSS clip-path 属性
深入理解与应用CSS clip-path 属性

clip-pathclip-path是什么clip-path 是一个CSS属性,允许开发者创建一个剪切区域,从而决定元素的哪些部分可见,哪些部分会被隐...

2024-10-25 11:51 citgpt

HCNP Routing&Switching之OSPF LSA类型(二)
  • HCNP Routing&Switching之OSPF LSA类型(二)
  • HCNP Routing&Switching之OSPF LSA类型(二)
  • HCNP Routing&Switching之OSPF LSA类型(二)
  • HCNP Routing&Switching之OSPF LSA类型(二)
Redis和Memcached的区别详解
  • Redis和Memcached的区别详解
  • Redis和Memcached的区别详解
  • Redis和Memcached的区别详解
  • Redis和Memcached的区别详解
Request.ServerVariables 大全

Request.ServerVariables("Url")返回服务器地址Request.ServerVariables("Path_Info")客户端提供的路...

python操作Kafka

目录一、python操作kafka1.python使用kafka生产者2.python使用kafka消费者3.使用docker中的kafka二、python操作kafka细...

Runtime.getRuntime().exec详解

Runtime.getRuntime().exec详解概述Runtime.getRuntime().exec用于调用外部可执行程序或系统命令,并重定向外部程序的标准输入、标准输出和标准错误到缓冲池。...

promise.all详解 promise.all是干什么的
promise.all详解 promise.all是干什么的

promise.all详解promise.all中所有的请求成功了,走.then(),在.then()中能得到一个数组,数组中是每个请求resolve抛出的结果...

2024-10-24 16:21 citgpt

Content-Length和Transfer-Encoding详解
  • Content-Length和Transfer-Encoding详解
  • Content-Length和Transfer-Encoding详解
  • Content-Length和Transfer-Encoding详解
  • Content-Length和Transfer-Encoding详解

取消回复欢迎 发表评论: