网络字节顺序

来源:互联网 发布:在线网络信托基金公司 编辑:程序博客网 时间:2024/06/05 23:43
网络字节顺序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,
从而可以保证数据在不同主机之间传输时能够被正确解释。网络字节顺序采用big endian排序方式。

1、网络与主机字节转换函数:htons ntohs htonl ntohl (s 就是short l是long h是host n是network)
2、不同的CPU上运行不同的操作系统,字节序也是不同的

为了进行转换 bsd socket提供了转换的函数 有下面四个
  htons把unsigned short类型从主机序转换到网络序
  htonl 把unsigned long类型从主机序转换到网络序
  ntohs 把unsigned short类型从网络序转换到主机序
  ntohl 把unsigned long类型从网络序转换到主机序
  在使用little endian的系统中 这些函数会把字节序进行转换
  在使用big endian类型的系统中 这些函数会定义成空宏
  同样 在网络程序开发时 或是跨平台开发时 也应该注意保证只用一种字节序 不然两方的解释不一样就会产生bug.

字节顺序是指占内存多于一个字节类型的数据在内存中的存放顺序,通常有小端、大端两种字节顺序。小端字节序指低字节数据存放在内存低地址处,
高字节数据存放在内存高地址处;大端字节序是高字节数据存放在低地址处,低字节数据存放在高地址处。

基于X86平台的PC机是小端字节序的,而有的嵌入式平台则是大端字节序的。因而对int、uint16、uint32等多于1字节类型的数据,在这些嵌入式平台上应该变换其存储顺序。
通常我们认为,在空中传输的字节的顺序即网络字节序为标准顺序,考虑到与协议的一致以及与同类其它平台产品的互通,在程序中发数据包时,将主机字节序转换为网络字节序,
收数据包处将网络字节序转换为主机字节序。
内存里是具体怎么存放的形式?为什么会有CPU解释的不同?数据不是按12345678……这样的顺序一直排列的么?

如: 一个多字节值 0xFECDBA98,内存从地址100开始存放

降序: FE 对应地址100 | CD 对应地址 101 | BA 对应地址 102 | 98 对应地址 103

升序: 98 | BA | CD | FE ---->;same above

注意,我们的书写字数据表示法是从高字节位--->低字节位(从左到右)

内存地址生长方向为: 从左到右 由低到高(这是不变的)

数据为: 0x98BADCFE

降序(Big-endian)大端字节序存储时 由左到右

升序(Little-endian)小端字节序存储时 由右向左

案例1

如何手算主机字节顺序转换为网络字节顺序?
  

假设某16位的整数,主机字节顺序的值是21,那么它的网络字节顺序是多少?
  解决的步骤是:

1、将21化成二进制,二进制,如果不足16位就在其前面补0,补满16位。

21转换成二进制是:10101,在它前面补0,补满16位后就得到:

00000000#00010101

2、将这个16位二进制字符平分成两段,每段8位

0000000 000010101 == > 00000000#00010101

3、颠倒这两段的顺序,然后去掉第一个字符“1”前面的0,化成十进制就得到了网络字节顺序的值了。

00000000#00010101颠倒后:00010101#00000000

即00 01 01 01 00 000000

去掉第一个“1”前面的0得到:10 10 10 00 00 00 0

化成十进制得到:5376

inet_addr函数可以将一个点分十进制的IP地址转换成网络字节顺序的长整形十进制值。同样的,inet_ntoa函数将网络字节顺序的长整形十进制数值的IP地址转换成点分十进制。

0 0