大小端和字节对齐什么是大小端?小端(LittleEndian):常见的操作系统都是小端存储,各种编程语言在内存中也是

在不同的计算机体系结构中,对于数据(比特、字节、字等)的存储和传输机制有所不同;目前在各种体系结构的计算机中,主要采用的字节存储机制主要有两种:大端(Big-endian)和小端(Little-endian)。字节序,又称端序,尾序,英文:Endianness。在计算机科学领域中,字节序是指存放多字节数据的字节(byte)的顺序,典型的情况是整数在内存中的存放方式(小端)和网络传输的传输顺序(大端)。Endianness有时候也可以用指位序(bit)。

下面来看一个更具体的例子(我们只需要记住,整数在常见的x86cpu的架构中是按小端存储的,C/C++发送到网络的时候需要转换成大端)。

vs2017中,我们看一下uint32_t(无符号整数32位4字节)在内存中是什么样的:

这一串:07000000,所以是小端模式。

如果转换成大端呢?

前后2张图有什么不同?前者是直接打印uint32_t的内存地址,后者是通过evpp的Buffer类的AppendInt32函数,间接调用htonl把unsignedlong类型从主机序(x86cpu下是小端)转成网络字节序(大端)。

evpp(C++跨平台网络库)中2个转换函数细节如下:

typeImHeaderstruct{ Lengthuint32//thewholepdulength Versionuint16//pduversionnumber Flaguint16//notused ServiceIduint16// CommandIduint16// SeqNumuint16//包序号 Reverseduint16//保留 pbMessageproto.Message//消息体}像上面的头部,固定16字节。头4字节存放长度。假设我的服务端是用go开发的,按照大端解析,会造成什么后果?

第67行按照大端解析,本来客户端发送了数字7(代表数据部的长度是7),这边66行解析出来,自然就不对了,变成了117440512。所以后面也就没有办法正确的去取数据部的数据了,只能判断为坏包。

再来看一下内存:

我们看到开头:07000000,确实是小端,正确的大端应该是:00000007。

引用:

JAVA中所有的二进制文件都是按大端存储,这种存储方式也被称为networkorder。即在所有的平台上,如Mac、PC、UNIX等等运行JAVA,都不用考虑大小端的问题。麻烦的是不同语言开发的程序进行数据交换,如笔者最近的项目,二进制文件是由C生成的,通过redis消息通道以Json格式发过来,而C语言默认是小端模式,就涉及到大小端转换。有些平台(如Mac、IBM390)内置用的大端模式,其它一些平台内置用的小端模式(如Intel)。JAVA帮你屏蔽了各平台字节顺序的差异。

所以,java一般情况下不需要处理大小端问题,除非需要和其他语言如C/C++通信。

Java中虚拟机屏蔽了大小端问题,如果是Java之间通信则无需考虑。

只有在跨语言通信的场景下才需要处理大小端问题。比如使用Android使用Java,iOS使用Swift,服务端使用C++/GO,那么大家还是按照“网络字节序”的规矩发送(即大端),各个语言自行转换即可。

参考资料:

引用百度百科里面的一句话:

现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐

下面再来看2个概念,加深理解。

通常在C/C++程序员眼中,char*普遍存在的意思是“一块内存”,甚至Java也具有byte[]表示原始内存的类型。真的有这么简单吗?

计算机的处理器并不是以单个字节读取和写入内存。而是以2、4、8、16甚至32字节的块访问内存(为了提升性能)。我们将处理器访问内存的大小称为内存访问粒度。

所以,这就有1个问题,假设我定义了一个结构体,大小为5会怎么办(除不尽2)?先看完一下对齐基础,下一节:结构体对齐中会有解答。

但是,请注意从地址1读取时会发生什么。由于该地址未均匀地落在处理器的内存访问边界上,因此处理器还有很多工作要做。这样的地址称为不对齐地址(所以#pragmapack指令会让程序变慢?)。因为地址1是未对齐的,所以具有两字节粒度的处理器必须执行额外的内存访问,从而减慢了操作速度。

最后,检查在具有四字节内存访问粒度的处理器上会发生什么,例如68030或PowerPC601;

正是因为处理器的内存访问不是按照我们理解的1个字节1个字节的读取,所以,编译器势必会为我们做一些事情从而优化性能。接下来,我们看一下结构体对齐,了解编译器在背后做的一些工作。

这一次,我拿macbookpro2017来实验。

一个无辜的结构体:

structHeader{chara;//1个字节intb;//4个字节charc;//1个字节};此结构的大小(以字节为单位)是多少?直观上看应该是1+4+1等于6,真的是吗?我们看一下它在内存中的布局:

右图是macos中,clang编译器的内存布局,我们发现,真正的大小并不是6个字节,而是按照结构体中最大的值(int=4字节)对齐,即3*4=12。然后冗余。我们利用clion来调试(变量上悬浮->右击->ShowinMemoryView)确定一下:

确实是这样,那会造成2个问题:

那怎么办?

如果您不了解并解决软件中的对齐问题,则以下情况的严重程度从高到低都是可能的:

简单点说,错误的对齐方式会造成内存浪费,性能降低,甚至是解析错误造成崩溃。

验证的:

未验证的:

正确的做法,示例1:

structHeader{ intb;//4个字节 chara;//1个字节 charc;//1个字节 int16_treserved;//2个字节,对齐};示例2(所以,在我们自定义协议时,特别是业务头中的各个字段类型可不能随便设定,而是要根据最大的值的整数倍放置):

typeImHeaderstruct{ Lengthuint32//thewholepdulength Versionuint16//pduversionnumber Flaguint16//notused ServiceIduint16// CommandIduint16// SeqNumuint16//包序号 Reverseduint16//保留 pbMessageproto.Message//消息体}

THE END
1.C++网络编程初学者的开源项目码云周刊第41期互联网的兴起,让网络程序有了长足的发展,让我们可以通过网络编程在程序中实现计算机的通信。举个例子,当你使用浏览器访问码云时,你的计算机就和码云的某台服务器通过互联网连接起来了,然后,码云的服务器把网页内容作为数据通过互联网传输到你的电脑上。 当然,对于 C++ 网络编程的初学者,小编推荐下面6个还算不错的开https://cloud.tencent.com/developer/article/1078264
2.C在线工具菜鸟工具C 在线工具 AI 编程工具 复制 清空 下载 1 #include <stdio.h> 2 ? 3 int main() 4 { 5 /* Write C code in this online editor and run it. */ 6 printf("Hello, World! \n"); 7 8 return 0; 9 } Hello, World!Copyright ? JYSHARE.COM 2024 备案号:闽ICP备12019840号-4 https://c.runoob.com/compile/11/
3.socket编程——C++实现基于UDP协议的简单通信(含详解)c++udp在了解完socket编程的一些基本理论知识后,很想把理论应用到实践,直接搜项目实战的教程,但是在看了几篇博客文章和一些B站的教程后,发现大部分都是不易上手的基于UDP/TCP的聊天系统,不太适合刚接触C++网络编程的同学,所以这里用C++实现简单的UDP通信,可以帮助大家更好的了解socket编程中的一些重要步骤。 https://blog.csdn.net/m0_74203352/article/details/137405601
4.C++网络编程详细讲解C语言您的位置:首页→ 软件编程→ C 语言→ C++网络编程 C++网络编程详细讲解更新时间:2022年10月31日 10:39:23 作者:无水先生 计算机是通过TCP/IP协议进行互联从而进行通信的,为了把复杂的TCP/IP协议隐藏起来,更方便的实现计算机中两个程序进行通信,引出了socket这个概念https://www.jb51.net/article/266314.htm
5.C++网络编程之一网络框架介绍Clay的技术空间常用的网络框架 Boost.Asio:Boost.Asio 是一个跨平台的 C++ 网络编程库,提供了异步 I/O 操作的抽象。它可以处理 TCP、UDP、SSL 等协议,并提供了丰富的异步操作和事件处理机制。 POCO C++ Libraries:POCO 是一个功能强大的 C++ 类库,其中包含了丰富的网络通信模块,包括 HTTP、SMTP、POP3、FTP 等协议的支持,以及https://www.techgrow.cn/posts/27a1782a.html
6.c++网络编程TCP/IP最近闲暇时间多了,有了时间就下定决心学习学习 cpp,之前有一定 cpp 基础。所以 TCP/IP 为背景进行 cpp 的学习。先写一个简单 TCP 的服务端和客户端来体验一下。什么 TCP 呀 UDP 在开始接触网络编程时候是那么陌生,是那么遥远。 其实大家不要脱离实际,自己把他 magic 化,其实一切都是合乎常理和实际的。先从https://www.jianshu.com/p/203a98095122
7.c++网络验证C++网络编程电子书,包括了网络编程的各个方面,内含19个文档。 上传者:weixin_41839371时间:2018-03-16 易语言软件网络验证程序:丁丁神盾网络验证1.18免费版全套源码 这是丁丁神盾网络验证最后的一个免费版,同时也是功能最强大的一个免费版, 软件里带有易语言,按键精灵,C语言的使用源码以及服务器后台代码,使用其它语言https://www.iteye.com/resource/ljf5201-10518768
8.基于C++从0到1手写Linux高性能网络编程框架(超清)基于C++从0到1手写Linux高性能网络编程框架(超清) 网络编程:构建互联世界的基石 在当今数字化时代,网络编程已成为连接全球用户、设备与服务的核心技术。它允许开发者创建能够通过网络交换数据的应用程序,从简单的Web服务器到复杂的分布式系统,无不依赖于网络编程。本文将深入探讨网络编程的基本概念、关键技术、应用场景,https://blog.51cto.com/u_15958308/11412696
9.C++builder中基于SOCKET的网络编程.pdfC++builder中基于SOCKET的网络编程.pdf,计算机光盘软件与应用 软件设计开发 ComputerCDSoftwareandApplications 2012年第 6期 三、C++buiIder环境下的网络编程 1.创建客户机端的套接字并与服务器建立连接 C++bui]der中,网络组件TServerSocket和TC1ientSocket vo:id fashttps://max.book118.com/html/2017/0713/122069728.shtm
10.c++网络编程项目:flamingo一款高性能轻量级开源即时通讯软件服务器代码使用纯C++11开发,所以您的gcc/g++版本必须至少在4.7以上,推荐的版本是4.8.5。另外,使用cmake和makefile工具进行项目管理和编译,因此您需要安装cmake和makefile工具。 安装mysql。 使用的数据库是mysql,如果您使用的是CentOS 7.0及以上系统,需要安装 mariadb-server、mariadb-client 和mariadb-devel。如果https://github.com/balloonwj/flamingo
11.主干课程本课程以Java语言为描述语言,描述网络编程的体系结构、主要技术以及相应编码。内容包括:Java语言的平台无关性、Java程序的开发过程、小应用程序(Applet);图形用户界面设计(awt和swing);JDBC数据库访问技术;JavaBean开发和MVC设计模式;Servlet编程;输入输出流;Java多线程;访问Internet资源的相关技术;Socket编程:客户端套接字https://xxkx-ybxy.xaut.edu.cn/Undergraduate_Education/zgkc.htm
12.ZLToolKit:一个基于C++11的轻量级网络框架,基于线程池技术可以一个基于C++11简单易用的轻量级网络编程框架 项目特点 基于C++11开发,避免使用裸指针,代码稳定可靠;同时跨平台移植简单方便,代码清晰简洁。 使用epoll+线程池+异步网络IO模式开发,并发性能优越。 代码经过大量的稳定性、性能测试,可满足商用服务器项目。 支持linux、macos、ios、android、windows平台 https://toscode.mulanos.cn/xia-chu/ZLToolKit
13.Linux多线程服务端编程(豆瓣)曾在摩根士丹利IT 部门工作5 年,从事实时外汇交易系统开发。现在在美国加州硅谷某互联网大公司工作,从事大规模分布式系统的可靠性工程。编写了开源C++ 网络库muduo,参与翻译了《代码大全( 第2 版)》和《C++ 编程规范(繁体版)》,整理了《C++ Primer (第4 版)(评注版)》,并曾多次在各地技术大会演讲。https://book.douban.com/subject/20471211/
14.《Linux多线程服务端编程:使用muduoC++网络库(写给每一位C++程序当当网图书频道在线销售正版《Linux多线程服务端编程:使用muduo C++网络库(写给每一位C++程序员,功力为证,集编程思想、经验之大成)》,作者:陈硕,出版社:电子工业出版社。最新《Linux多线程服务端编程:使用muduo C++网络库(写给每一位C++程序员,功力为证,集编程思http://product.dangdang.com/23162953.html