一、什么是字节顺序?
字节顺序,是指数据在内存中的存放顺序。
举例说明什么是字节顺序
使用16进制表示两个数:0x12345678和0x11223344。在内存中有两种方法存储这两个数字,分别为:
从上图看,两种方案虽有不同,但也有共识,即依次存储每一个数字,即先存0x12345678,再存0x11223344。大家的不同在于,对于某一个要表示的值,是把值的低位存到低地址,还是把值的高位存到低地址。
二、字节顺序的分类
字节的排列方式有两种。例如,将一个多字节对象的低位放在较小的地址处,高位放在较大的地址处,则称小端序;反之则称大端序。
在几乎所有的机器上,多字节对象都被存储为连续的字节序列。例如在C语言中,一个类型为int的变量x地址为0x100,那么其对应地址表达式&x的值为0x100。且x的四个字节将被存储在电脑内存的0x100, 0x101, 0x102, 0x103位置。
(1)大端、小端模式的区别
例如假设变量x类型为int,位于地址0x100处,它的值为0x01234567,地址范围为0x100~0x103字节,其内部排列顺序依赖于机器的类型。大端法从首位开始将是:0x100: 0x01, 0x101: 0x23,..。而小端法将是:0x100: 0x67, 0x101: 0x45,..。
(2)不同处理器体系
● x86,MOS Technology 6502,Z80,VAX,PDP-11等处理器为Little endian。
● Motorola 6800,Motorola 68000,PowerPC 970,System/370,SPARC(除V9外)等处理器为Big endian。
● ARM, PowerPC (除PowerPC 970外), DEC Alpha, SPARC V9, MIPS, PA-RISC and IA64的字节序是可配置的。
三、网络字节序
对于搞网络通信应用(比如IM、消息推送、实时音视频)开发的程序员来说,自已写通信底层的话是一定会遇到大小端问题,上面所说的大小端字节序都是在说计算机自己,也被称作主机字节序。同型号计算机上写的程序,在相同的系统上面运行是没有问题的。
但计算机网络的出现让大小端问题变的复杂化了,因为每个计算机都有自己的主机字节序。不同计算机之间通过网络通信时:我“说”的你听不懂,你“说”我也听不懂,这可怎么办?这时候就需要约定俗成的协议来解决问题。
TCP/IP协议很好的解决了这个问题,TCP/IP协议规定使用“大端”字节序作为网络字节序。
这样不管计算机采用哪种字节序,发送数据的时候必须将自己的主机字节序转换为网络字节序(即“大端”字节序),对接收到的数据转换为自己的主机字节序。这样一来,也就达到了与CPU、操作系统无关,实现了网络通信的标准化。
● 主机字节序到网络字节序的转换
为了程序的兼容,网络通信过程中每次发送和接受数据都要进行转换,这样做的目的是保证代码在任何计算机上执行时都能达到预期的效果。
通信时的这种常用的操作,Socket API这一层,一般都提供了封装好的转换函数,方便程序员使用。比如从主机字节序到网络字节序的转换函数:htons、htonl(C语言中常用),从网络字节序到主机字节序的转换函数:ntohs、ntohl(C语言中常用)。当然,明白了原理后也可以编写自己的转换函数。
本文固定URL:https://www.dotcpp.com/course/1031
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程