Big-endian

二进制读写中的大字端(Big Endian)和小字端(Little Endian) Big Endian and Little Endian 阅读详情

java与 C++ 之间进行 SOCKET 通讯要点简要解析

作者:看引擎出处:博客2013-07-11 06:57

  Endian定义: 在计算机系统体系结构中用来描述在多字节数中各个字节的存储顺序。

  big-endian也称高位在前、大端在前。是 计算机体系结构中一种描述多字节存储顺序的术语,在这种机制中最重要字节(MSB )存放在最低端的地址 上。采用这种机制的处理器有Mortolora PowerPC 微处理器系列和绝大多数的 RISC 处理器。

  big-endian 最直观的字节序:

  内存地址从左到右与值由低到高的顺序相对应。

  little-endian也称低位在前、小端在前。 计算机体系结构中一种描述多字节存储顺序的术语,在这种机 制中最不重要字节(LSB )存放在最低端的地 址上。采用这种机制的处理器有 Intel x86 系列微处理器和一些网络通信设备。该术语除了描述多字节存储顺序外还常常用来描述一个字节中各个比特的排放次序 ,这里仅讨论多字节存储循序 。

  little-endian是最符合人的思维的字节序,低与低,高与高一一对应:

  地址低位存储值的低位

  地址高位存储值的高位

  下面举一个例子具体说明 big-endian 与 little-endian:

  int nValue = 0×01020304;

  上面的整型nValue 有 4 个字节,其中 01 为最高位的字节, 04 为最低位的字节。那么在内存(或文件)中,该值的存储循序为:

  内存(或文件)地址:0×12000001 0×12000002 0×12000003 0×12000004

  Big-endian : 01 02 03 04

  Little-endian : 04 03 02 01

  如果用一个byte 数组来保存的话,也就是如下:

  Big-endian模式下: byte byValue[] = {0×01, 0×02, 0×03, 0×04};

  Little-endian模式下: byte byValue[] = {0×04, 0×03, 0×02, 0×01};

  Big-endian 或是 little-endian的判断:

  bool IsLittleEndian ()

  {

  int i = 1;

  char * p = ( char *)& i ;

  i f ( * p = 1 )

  return true ; // 小端

  else

  return false ; // 大端

  }

  在各种计算机体系结构中,对于字节、字等的存储机制有所不同,因而引发了计算机通信领域中一个很重要的问题,即通信双方交流的信息单元(比特、字节、字、双字等等)应该以什么样的顺序进行传送。如果不达成一致的规则, 通信双方 将无法进行正确的编/ 译码从而导致通信失败。

  通常所说的网络字节序(Network Byte Order )就是遵循 big-endian 规则。实际通信过程中,通信双方需要把数据按照 big-endian 编码再通过网络传输。

  通常所说的主机字节序(Host Byte Order ),与 CPU 的字节序一致。 x86 系列主机的字节序都是 little-endian 桂册。所有 little-endian 规则主机直接通过网络通讯的时候,需要进行字节序转化。

  为了进行转换 bsd socket 提供了转换的函数 有下面四个

  htons 把 unsigned short 类型从主机 字节 序转换到 网络字节序

  htonl 把 unsigned long 类型从主机 字节 序转换到 网络字节序

  ntohs 把 unsigned short 类型从 网络字节序 转换到主机 字节 序

  ntohl 把 unsigned long 类型从网络 字节 序转换到主机 字节 序

  在使用little endian 的系统中这些函数会把字节序进行转换

  在使用big endian 类型的系统中这些函数会定义成空宏

  由于Java 运行需要自己的虚拟机来支持,所以 Java 程序所支持的字节序与 Java 虚拟机一致。Java 虚拟机遵循的是 big-endian 规则。所以可以把 Java 字节序看作是遵循 big-endian 规则的主机字节序。

  4.1 字节序问题

  一直以来都在进行着C++ 上面的网络开发,发现在 C++ 上面进行通讯的时候,基本上都没有考虑到网络字节序的问题,特别是网络应用中的用户数据。大家都知道网络通讯传输的都是字节流的数据,于是都是定义一个 char 类型的缓冲区,然后不管 int , WORD, DWORD 还是其他自定义类型的结构对象也好,都直接 memcpy() 拷贝到缓冲区,直接发送出去了,根本都没有考虑所传输数据的网络字节序问题。如果非要说一点关注了网络字节序问题的话,那就是有一个地方,大家都回去用到的,也就是网络通讯端口,把端口号赋值给 sockaddr_in .sin_port之时大家都会使用了htons() ,也就是把端口号从主机字节序转化为网络字节序。

  因为这些程序的服务器端也好,客户端也好,都是在x86 系列系统下运行,并且都是 C++ 编译出来的,所以不会因为字节序而出现问题。

  现在所做项目,涉及到Java 与 C++ 之间的 SOCKET 通讯,这样的情况下,就需要大家都按规则来办事了, C++ 方面传输的多字节类型数据还请从主机字节序转化成网络字节序再进行传输。

  当然,数据是由程序员来组合的,也是由程序员来解析的,所以如果不按标准行事也是可以的。但是就需要在解析数据的时候注意好了。

  建议还是按标准行事,把数据转化成网络字节序。

  PS:

  Java与 Windows 平台下其他开发语言之间进行数据交与,也需要遵循该原则;

  Java下读写 Windows 平台下其他开发语言保存的数据,或是 Windows 平台下其他语言读写Java 保存的数据,也需要注意字节序问题。

  4.2 字节对齐问题

  #include 

  using namespace std ;

  typedef struct tag_S1

  {

  char s_szValue [8];

  char s_cValue ;

  } S1 ;

  typedef struct tag_S2

  {

  int s_nValue1 ;

  char s_szValue [8];

  char s_cValue ;

  int s_nValue2 ;

  } S2 ;

  typedef struct tag_S3

  {

  int s_nValue ;

  char s_cValue ;

  } S3 ;

  #pragma pack ( push , 1)

  typedef struct tag_S4

  {

  int s_nValue ;

  char s_cValue ;

  } S4 ;

  #pragma pack ( pop )

  int main ( int argc , char * argv [])

  {

  cout << “sizeof(S1):” << sizeof ( S1 ) << endl ;

  cout << “sizeof(S2):” << sizeof ( S2 ) << endl ;

  cout << “sizeof(S3):” << sizeof ( S3 ) << endl ;

  cout << “sizeof(S4):” << sizeof ( S4 ) << endl ;

  system ( “pause” );

  return 0;

  }

  上面的程序在 WinXP sp3 + VS2008Sp1下运行结果如下:

  sizeof(S1):9

  sizeof(S2):20

  sizeof(S3):8

  sizeof(S4):5

  请按任意键继续. . .

  Win32位平台下的微软 C 编译器 (cl.exe for 80×86) 的对齐策略:

  1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;

  备注:编译器在给结构体开辟空间时,首先找到结构体中最宽的基本数据类型,然后寻找内存地址能被该基本数据类型所整除的位置,作为结构体的首地址。将这个最宽的基本数据类型的大小作为上面介绍的对齐模数。

  2) 结构体每个成员相对于结构体首地址的偏移量( offset )都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节( internal adding );

  备注: 为结构体的一个成员开辟空间之前,编译器首先检查预开辟空间的首地址相对于结构体首地址的偏移是否是本成员的整数倍,若是,则存放本成员,反之,则在本成员和上一个成员之间填充一定的字节,以达到整数倍的要求,也就是将预开辟空间的首地址后移几个字节。

  3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要,编译器会在最末一个成员之后加上填充字节( trailing padding )。

  备注:结构体总大小是包括填充字节,最后一个成员满足上面两条以外,还必须满足第三条,否则就必须在最后填充几个字节以达到本条要求。

  Windows 32位系统下, VC 中,默认的字节对齐方式是 4 字节对齐。

  sizeof(S1) :因为结构中数据类型都是 char ,最宽基本类型大小是 1 ,所以结构大小为 9, S1 没有进行填充;

  sizeof(S2)、 sizeof(S3) : S2 , S3 就被填充了一定的字节;

  sizeof(S4):因为设置了对齐方式为 1 字节对齐,所以不会被填充。

  在Java 与 C++ 进行 SOCKET 通讯的 C++ 端程序,建议涉及网络通讯的结构使用 1 字节对齐方式,不然 Java 端会增加数据处理的复杂度。

  4.3 Java与 C++ 之间基本数据类型的差别

  需要注意以下几个数据类型的区别(32 位系统下 ) :

  C++ Java

  char———1byte Byte———-1byte

  Char———-2byte2

  long———4bytes long———-8bytes

  注意:

  Java中的 Char 是一个字符,而不是一个字节,与 VC 的 WORD 长度一致;

  Java中的 Byte 是一个字节,与 C++ 中的 char 含义一致,而 VC 中的 BYTE 是无符号的char ;

  Java中的 long 长度为 8 ,而 VC 中的 long 长度为 4 ( C++ 中 short , long 的长度跟编译器的实现相关)。

NL2SQL vs NL2Semantic2SQL:为什么你的智能问数项目总在SQL层卡壳? 本文深入剖析了智能问数项目中NL2SQL与NL2Semantic2SQL两种技术路线的核心差异。传统NL2SQL方案易导致宽表爆炸、口径混乱等工程困境,而引入语义层的NL2Semantic2SQL路线通过集中定义业务指标与维度,从根本上解决了数据一致性、维护成本与敏捷响应难题,是构建可持续、可治理智能数据查询系统的关键架构选择。 阅读详情

相关推荐

OpenHarmony实战开发-如何实现文件分布式同步编辑

在分布式文件场景中,分布式设备管理包含了分布式设备搜索、分布式设备列表弹窗、远端设备拉起三部分。首先在分布式组网内搜索设备,然后把设备展示到分布式设备列表弹窗中,最后根据用户的选择拉起远端设备。两台设备组网的分布式场景是工作中常常需要的。这样的分布式场景有助于加快工作效率,减少工作中的冗余,本例将为大家介绍如何实现上述功能。​ (2)订阅分布式数据变化:通过this.distributedObject.on(‘status’, this.statusCallback)监听分布式数据对象的变更。

2401_82546228的博客 731

字节序:Big Endian 和 Little Endian

字节序 字节序,也就是字节的顺序,指的是多字节的数据在内存中的存放顺序。 在几乎所有的机器上,多字节对象都被存储为连续的字节序列。例如:如果C/C++中的一个int型变量 a 的起始地址是&a = 0x100,那么 a 的四个字节将被存储在存储器的0x100, 0x101, 0x102, 0x103位置。 根据整数 a 在连续的 4 byte 内存中的存储顺序,字节序被分为大端序(Big Endian) 与 小端序(Little Endian)两类。 然后就牵涉出两大CPU派系: Motorola

OceanStar的博客 9000

大端和小端传输字节序

大端和小端 在计算机中是以字节为单位,每一个地址对应一个字节,一个字节8bit。在C中,除了8bit的char以外,还有16bit的short,32位的int,64位long,当然具体要由编译器决定,可以通过sizeof来获取不同类型在内存中占用的字节数。在计算机系统中,当物理单位的长度大于1个字节时,就要区分字节顺序。常见的字节顺序有两种:Big Endian(High-byte first) 和 Litter Endian(Low-byte first),当然还有其他字节顺序,但不常见,例如Middle

类人_猿的博客 9896

Big Endian和Little Endiand的区别

一、字节序 谈到字节序的问题,必然牵涉到两大CPU派系。那就是Motorola的PowerPC系列CPU和Intel的x86系列CPU。PowerPC系列采用big endian方式存储数据,而x86系列则采用little endian方式存储数据。那么究竟什么是big endian,什么又是little endian呢?      其实big endian是指低地址存放最高有效字节(MSB),而little endian则是低地址存放最低有效字节(LSB)。 &nb

gao_zhennan的博客 2661

【协议森林】详解大端(big endian)与小端(little endian)

1、字节序 字节顺序,又称端序或尾序(英语:Endianness)。在几乎所有的机器上,多字节对象都被存储为连续的字节序列。例如在C语言中,一个类型为int的变量x地址为0x100,那么其对应地址表达式&x的值为0x100。且x的四个字节将被存储在存储器的0x100, 0x101, 0x102, 0x103位置,这就是所谓的字节序。字节存放的顺序有两种模式:大端模式和小端模式。 2、大小端...

平凡的世界 4509

Text-to-SQL与智能问数完全指南:基本概念、核心原理、Python实战教学及企业项目落地

本文介绍了Text-to-SQL与智能问数技术如何解决企业数据分析痛点。通过分析四个典型场景,揭示数据使用门槛高的问题。Text-to-SQL将自然语言转换为SQL查询,包含语义理解、数据库模式感知和SQL生成三大核心环节。智能问数则融合多种技术,实现自然语言交互式数据分析。文章对比了四种主流技术路线,并指出语义层在准确性上的优势。这项技术正在推动"人人都是数据分析师"的数字化转型。

【javatoai17819112191】→Java && python && AI Agent工程师 3051

Sql Server 查询今天,昨天,近七天....数据

1 今天数据:select * from 表名 where DateDiff(dd,datetime类型字段,getdate())=0 2 昨天数据:select * from 表名 where DateDiff(dd,datetime类型字段,getdate())=1 3 7天内数据:select * from 表名 where DateDiff(dd,datetime类...

2239

SQL查询今天,指定日期的数据

本月有多少天:select datepart(dd,dateadd(dd,-1,dateadd(mm,1,cast((cast(year(getdate()) as varchar)+'-'+cast(month(getdate()) as varchar)+'-01' ) as。查询本月最后一天日期:Select dateadd(ms,-3,DATEADD(mm, DATEDIFF(m,0,getdate())+1, 0)) as lastday //修改-3的值会有相应的变化。

qq_37159134的博客 2236

SQL语句统计每天、每月、每年、今天、昨天、本周、上周的数据

统计每月 --这种形式只能查数据库存在的日期 比如数据库只有到六月分的 那六月以后的就没有 select 需要的字段, month ( 日期字段) as 月份, sum( 要统计的字段) as 总数 from 表 where year ( 日期字段) = DATEPART(year, GETDATE()) -- 要查某年 这里获取当年 group by 需要的字...

你要明白,任何问题都不是孤立存在的,一定有人曾经遇到过,并且已经有更好的解决办法了,只是我还不知道。我不应该在黑暗中独自前行,去重新发明轮子,也许我的顿悟,只是别人的基本功!我应该要站在巨人的肩膀上,学习更成熟的经验和方法,然后再来解决这个问题 6527

大端模式(big-endian)与小端模式(little-endian

参考自大端模式与小端模式 大端模式是指数据的低位保存在内存的高地址中,而数据的高位保存在内存的低地址中. 小端模式是指数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中。 大小端模式的由来在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8bit。但是在C语言中除了8bit的char之外,还有16bit的short型,32bit的long型(要看具体的编译器

jason_cuijiahui的博客 2万+

大端 和 小端(Big-endian和Little-endian

战争开始是由于以下的原因:我们大家都认为,吃鸡蛋前,原始的方法是打破鸡蛋较大的一端,可是当今皇帝的祖父小时候吃鸡蛋,一次按古法打鸡蛋时碰巧将一个手指弄破了,因此他的父亲,当时的皇帝,就下了一道敕令,命令全体臣民吃鸡蛋时打破鸡蛋较小的一端,违令者重罚。叛乱平息后,流亡的人总是逃到那个帝国去寻救避难。关于这一争端,曾出版过几百本大部著作,不过大端派的书一直是受禁的,法律也规定该派的任何人不得做官。Cohen,一位网络协议的早期开创者,第一次使用这两个术语来指代字节顺序[25],后来这个术语被广泛接纳了。

二分掌柜的 8900

大端(Big Endian)和小端(Little Endian)的区别

大端(Big Endian)和小端(Little Endian)的区别 背景 在C/C++中,我们经常会处理位运算。不同的系统字节的排列就不一样,有的系统是大端排列,有的系统是小端排列。因此,处理位运算也会因不同的系统而不一样。下面我来介绍一下大端(Big Endian)和小端(Little Endian)的区别。 大端 小端 测试代码 总结:

冰冻三尺非一日之寒 1万+

大端存储(Big-Endian)和小端存储(Little-Endian)讲解

特性大端存储 (Big-Endian)小端存储 (Little-Endian)最高有效字节 (MSB)存储在最低内存地址存储在最高内存地址最低有效字节 (LSB)存储在最高内存地址存储在最低内存地址内存顺序数值高位 -> 低地址,数值低位 -> 高地址数值低位 -> 低地址,数值高位 -> 高地址直观性高(内存转储顺序即数值顺序)低(内存转储顺序是数值的逆序)CPU运算亲和性一般可能更好(从低位开始运算)网络传输标准是(网络字节序)否 (需转换为网络字节序)常见架构。

曾经也曾立志 2261

大小端跟什么有关_什么是大小端模式?

来源:百度百科及https://www.cnblogs.com/Alandre/p/4878841.html一、什么是大小端模式?大端模式(Big-Endian),是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中。小端模式(Little-Endian),是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中。二、名字由来在乔纳森·斯威夫特的著名...

weixin_42412194的博客 1283

大端模式小端模式详解(不懂你打我,略略~~)

大端模式小端模式简解(不懂你打我,略略~~) 先看概念 大端模式(Big-Endian),是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;这和我们的阅读习惯一致。 小端模式(Little-Endian),是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低。 先看两者概念中粗体字后面

jokerMingge的博客 5919

什么是Little EndianBig Endian?(Endianness:字节序、端序、尾序)

当数据在网络传输或磁盘存储时,都是以字节为单位,而每字节占8bit;那多字节数据如int,以什么顺序读写字节、如何组装成最终输出的数据呢?

reading-conference-writing 8461

C语言程序设计 | 大端小端存储解析以及判断方法

当我们在C语言中查看数据在内存中的存储时,我们经常会发现一个很奇怪的现象,什么现象呢? 例如下面这段代码 int main() { int i = 1; return 0; } 数据在内存中的存放方式似乎和我们想象的顺序不太一样,在我们的常规认知不一样,在我们的常规认知中,它的存放方式应该是00 00 00 01,那造成这个的原因是什么呢? 因为C语言在内存中存放数据时采用了两种存储模式,...

凌桓丶的博客 1103

计算机系统中的大端(Big-Endian)和小端(Little-Endian

如果硬件设备(如某些网络接口卡、存储控制器、嵌入式外设)使用的字节序与CPU不同,驱动程序在进行DMA操作或直接访问设备寄存器/内存缓冲区时,必须负责进行必要的字节序转换。如果两个运行在不同架构(如小端的x86和大端的PowerPC)上的程序需要通过文件、共享内存(需要两端一致)或其他非网络方式直接交换二进制数据,且没有明确的协议定义字节序,就会导致数据解析错误。如果程序运行的平台字节序与文件格式规定的字节序不同,就需要进行转换。这是为了确保不同架构的机器通过网络通信时,对数据的解释是唯一的。

chongjian1990的博客 3408

Big-endian and Little-endian (大小端)

字节序(Endianness) 在计算中,字节序是指数字的二进制表示形式中字节(或有时是位)的顺序。它也可以更一般地用于指代任何表示形式的内部排序,例如数字系统中的数字或日期的各个部分。 在最常见的用法中,字节顺序表示多字节数字中字节的顺序。big-endian顺序将最高有效字节排在最前面,最低有效字节排在最后,而little-endian的顺序则正好相反。例如,考虑无符号十六进制数0x1234,...

Jeff_的博客 1551

获取微信公众号历史文章列表页链接

action=home&__biz=这里替换你的biz==4、链接分享、发送到微信即可访问,注意该链接仅可在微信客户端使用,外部浏览器无法打开。3、拼接通用公式生成链接即为微信公众号历史文章列表链接。,如下图找到红框部分值,复制即为上文biz值。2、浏览器右键查看网页源码,新开页面搜索(1、复制公众号任意文章的链接在浏览器打开。

珞瑜的博客 7530

上市公司-是否为高科技行业(1990-2024年),包含五种高科技行业分类方式,参考文献,代码,最终结果

1、资源内容地址:https://blog.csdn.net/2301_79696294/article/details/1535352322、数据特点:今年全新,手工精心整理,放心引用,数据来自权威,且标注《数据来源》,相对于其他人的控制变量数据准确很多,适合写论文做实证用 ,不会出现数据造假问题3、适用对象:大学生,本科生,研究生小白可用,容易上手!!!4、课程引用: 经济学,地理学,城市规划与城市研究,公共政策与管理,社会学,商业与管理

上一篇: C++ Memory Management
下一篇: BT
screaming
博客等级 码龄19年 61粉丝 6原创
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值