首页 > 其他分享 >网络字节与主机字节序的转换函数实践

网络字节与主机字节序的转换函数实践

时间:2022-10-08 21:37:18浏览次数:48  
标签:Little 字节 主机 存放 Big endian CPU 函数

 

1.为什么要进行转换?

1.1在进行网络编程时,由于网络字节的顺序和主机的字节顺序可能存在不同,需要进行转换以统一“格式”

2.什么是网络字节顺序和主机字节顺序呢?

2.1网络字节顺序NBO(Network Byte Order):

网络字节顺序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释。网络字节顺序采用big endian排序方式,统一格式可以避免兼容性问题。

2.2主机字节顺序(HBO,Host Byte Order):

不同的机器的主机字节顺序(HBO)不一定相同,与CPU设计有关。

详解:

不同的CPU有不同的字节序类型 这些字节序是指整数在内存中保存的顺序 这个叫做主机序

最常见的有两种

1.Little-endian:将低序字节存储在起始地址

2.Big-endian :将高序字节存储在起始地址

LE(little-endian)将地址低位存储值的低位,将地址高位存储值的高位,是最符合人的思维的字节序。因为从人的思维来说低位值小,就应该放在内存地址小的地方,也即内存地址低位;反之,高位值大就应该放在内存地址大的地方,也即内存地址高位。

BE(big-endian)的地址低位存储的是值的高位,地址高位存储的是值的低位,它是最直观的字节序。说直观是它不需要考虑对应关系,只需要把内存地址从左到右按照由低到高的顺序写出;把值按照通常的高位到低位的顺序写出,两者对照,一个字节一个字节的填充进去。例如:

在内存中双字0x01020304的存储方式

内存地址

4000 4001 4002 4003

LE 04 03 02 01

BE 01 02 03 04

如果我们将0x1234abcd写入到以0x0000开始的内存中,则结果为

内存地址BE LE

0x0000 0x12 0xcd

0x0001 0x23 0xab

0x0002 0xab 0x34

0x0003 0xcd 0x12

通常来说,x86 cpu是Little-Endian。而一般ARM CPU也是Little-Endian。

但是当前常见的开发板使用的处理器比如S3C2410A、S3C2440等都是大小端支持的,可以通过软件选择。

3.如何进行网络字节顺序和主机字节顺序的转换?

网络中传输的数据有的和本地字节存储顺序一致,而有的则截然不同,为了数据的一致性,就要把本地的数据转换成网络上使用的格式,然后发送出去,接收的时候也是一样的,经过转换然后才去使用这些数据,基本的库函数中提供了这样的可以进行字节转换的函数,如和htons( ) htonl( ) ntohs( ) ntohl( ),这里n表示network,h表示host,htons( ) htonl( )用于本地字节向网络字节转换的场合,s表示short,即对2字节操作,l表示long即对4字节操作。同样ntohs( )ntohl( )用于网络字节向本地格式转换的场合

1、htons 把unsigned short类型从主机序转换到网络序

2、htonl 把unsigned long类型从主机序转换到网络序

3、ntohs 把unsigned short类型从网络序转换到主机序

4、ntohl 把unsigned long类型从网络序转换到主机序

在使用little endian的系统中 这些函数会把字节序进行转换,在使用big endian类型的系统中这些函数会定义成空宏。其他类型字节序转换long long 类型的网络字节顺序转换可以通过位移的方式实现。

4.拓展部分(详细介绍)

一、字节序

字节序:是指整数在内存中保存的顺序。

字节序有两种实现方式:

小端字节序(little endian):低字节数据存放在内存低地址处,高字节数据存放在内存高地址处。

大端字节序(bigendian):高字节数据存放在低地址处,低字节数据存放在高地址处。

大字节序更符合我们的阅读习惯。但是我们的主机使用的是哪种字节序取决于CPU,不同的CPU型号有不同的选择。

那么如何确定我们主机使用的哪种字节序。

如图所示:

 

4.1例子

嵌入式系统开发者应该对Little-endian和Big-endian模式非常了解。采用Little-endian模式的CPU对操作数的存放方式是从低字节到高字节,而Big-endian模式对操作数的存放方式是从高字节到低字节。

例如,16bit宽的数0x1234在Little-endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:

内存地址 存放内容

0x4001 0x12

0x4000 0x34

而在Big-endian模式CPU内存中的存放方式则为:

内存地址 存放内容

0x4001 0x34

0x4000 0x12

32bit宽的数0x12345678在Little-endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:

内存地址 存放内容

0x4003 0x12

0x4002 0x34

0x4001 0x56

0x4000 0x78

而在Big-endian模式CPU内存中的存放方式则为:

内存地址 存放内容

0x4003 0x78

0x4002 0x56

0x4001 0x34

0x4000 0x12

不同的CPU上运行不同的操作系统,字节序也是不同的

部分情况参见下表。

处理器 操作系统 字节排序

Alpha 全部 Little endian

HP-PA NT Little endian

HP-PA UNIX Big endian

Intelx86 全部 Little endian <-----x86系统是小端字节序系统

Motorola680x() 全部 Big endian

MIPS NT Little endian

MIPS UNIX Big endian

PowerPC NT Little endian

PowerPC 非NT Big endian <-----PPC系统是大端字节序系统

RS/6000 UNIX Big endian

SPARC UNIX Big endian

IXP1200 ARM核心 全部 Little endian

标签:Little,字节,主机,存放,Big,endian,CPU,函数
From: https://www.cnblogs.com/Chenyuyan123/p/16770257.html

相关文章