网络编程:主机字节序和网络字节序

  最近在使用python开发一个用于测试引擎服务的通用测试工具,这里梳理一下网络编程中不可避免遇到的网络编程中的一个概念:主机字节序和网络字节序。

      这里首先介绍一下小端模式(LE little-endian)和大端模式(BE big-endian)。

  1. 小端模式:
      小端模式最符合人的思维的字节序:即地址低位存储值的低位,地址高位存储值的高位,怎么讲是最符合人的思维的字节序,是因为从人的第一观感来说低位值小,就应该放在内存地址小的地方,也即内存地址低位反之,高位值就应该放在内存地址大的地方,也即内存地址高位。例如,在小端模式下,数据0x12345678在内存中的存放形式为:

  2.大端模式

      大端模式是最直观的字节序,地址低位存储值的高位,地址高位存储值的低位。为什么说直观,不要考虑对应关系只需要把内存地址从左到右按照由低到高的顺序写出,把值按照通常的高位到低位的顺序写出 两者对照,一个字节一个字节的填充进去。例如,在大端模式下,数据0x12345678在内存中的存放形式为:

 

  3.为什么会存在大小端之分呢?

      这是因为每个处理器厂商的处理器在处理数据存放时采用的策略不同导致的。在计算机系统中,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如果将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。

  例如一个16bit的short型x,在内存中的地址为0x0010,x的值为0x1122,那么0x11为高字节,0x22为低字节。对于大端模式,就将0x11放在低地址中,即0x0010中,0x22放在高地址中,即0x0011中。小端模式,刚好相反。我们常用的X86结构是小端模式,而KEIL C51则为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。

  4.如何判断自己的机器为大端模式还是小端模式

         机器字节序是大端模式还是小端模式有处理器的类型和安装的操作系统相关。一般情况下,我们可以通过一段C++小代码测试一下自己的机器是何种模式。我这里写了一段c++的代码,定据整形数据data=0x12345678,并用char * 指针p指向data的首地址,如果p指向的字节内容是0x12,则表明是本机是大端模式,如果p指向的字节内容是0x78,则表明是小段模式。代码如下:

 1 #include <iostream>
 2 int main()
 3 {
 4         int i=sizeof(int);
 5         std::cout<<i<<std::endl;
 6         int data=0x12345678;
 7         char *p=(char *)&data;
 8         if(*p==0x12)
 9         {
10                 std::cout<<"big end"<<std::endl;
11         }
12         if(*p==0x78)
13         {
14                 std::cout<<"small end"<<std::endl;
15         }
16         return 1;
17 }

5.主机字节序和网络字节序

  所谓主机字节序就是自己的主机内部(可按照第4节中的代码获取),内存中数据的处理方式,要么是大端,要么是小端。网络字节序指的是大端模式的字节序。

  数据在网络传输的过程中,一定有一个标准化的过程,也就是说:从主机a到主机b进行通信,a的固有数据存储-------标准化--------转化成b的固有格式

  如上而言:a或者b的固有数据存储格式就是自己的主机字节序,上面的标准化就是网络字节序(也就是大端字节序):a的主机字节序----------网络字节序 ---------b的主机字节序。

  那么,何时需要进行主机字节序到网络字节序的转换呢?

  1)如果主机a和主机b的主机字节序不一致,例如:主机a为大端模式,主机b为小端模式,则a在发送数据前应该进行主机字节序到网络字节序的转换(可以不进行,因为主机a的字节序和网络字节序一样,都是大端字节序),主机b在接收到数据时,必须进行网络字节序到主机字节序的转换,即大端到小端的转换。

  2)如果主机a和主机b的字节序是一样的,假设都为小端模式,则在数据传输时,可以不进行主机字节序到网络字节序的转换。如果有一天我把主机a上的这段程序移植到了主机c(大端字节序),并用主机c和主机b进行通信,由于主机c和b的字节序不一致,这样就会出现数据值解析错误的问题。

  因此,在实际的工程应用中,无论主机a和b的字节序,是否一样,为了程序的可移植性和兼容性,都建议数据发送主机进行主机字节序到网络字节序的转换,数据接收机进行网络字节序到主机字节序的转换。

原文地址:https://www.cnblogs.com/litaozijin/p/6506305.html