大端 小端 主机 网络 字节序

       说实话这个东西困扰了我一段时间了,尤其是搀和进来网络字节序的时候,真是懵懂纠结啊。。。

缘起

       最初接触是从变量内存布局时知道的,大端小端还是蛮好理解的:大端(big endian)就是高位字节存放到内存的低地址,而小端(little endian)是高位字节存放到内存的高地址。从内存布局的角度来界定就是所谓的主机字节顺序。我们比较常用和熟悉的X86就是采用小端存储,当然还有一些其他的系统及嵌入式系统采用的是大端。

就X86的小端存储举个小例子:

有一个long型变量(当然占4个字节),16进制表示为0x12 23 34 45,显然0X12就是所谓的高位,依次向右逐渐低位。在栈上如下列左侧的布局:

栈底(高地址)                                                            栈底(高地址)

-------------------                                                             ---------------------

     0x12                                                                              0x45

------------------                                                               --------------------

     0x23                   小端《==对比==》大端                      0x34

------------------                                                               ---------------------

     0x34                                                                              0x23

------------------                                                              ---------------------

     0x45                                                                              0x12

-------------------                                                             ---------------------

栈顶(低地址)                                                            栈顶(低地址)

如果以一个char*指向这个long的起始地址,以此取出这四个字节,就看出来顺序的差异了。

纠结:

        以上的对内存布局了解一些就不难理解。但是搀和进来网络字节序的时候,我的疑问就出来了:

1、网络传输就是一串比特流,没什么所谓的内存布局啊。

2、我主机字节序的传输过去就行了啊,那边也是主机字节序的,有什么影响呢?干嘛要转化。

3、主机字节序网络字节序什么时候转化什么时候不转化呢?

        反正就是一串纠结,陷进了自己思意的怪圈,爬不出来。

理解:

首先,字节序是字节的序列,不是bit的序列。这个看似直白的应该一开始就注意到的重点却是走出纠结的关键。

其次,低地址到高地址的一串内存空间其实完全就是0-7bit,8-15bit,16-23bit,24-31bit一串共32个bits而已。那么跟网络字节序就对应起来了。不用纠结网络传输的bit流没内存布局一事。

而《TCP/IP详解(一)》在提到网络字节序使用大端时,大致就是这么展示的。高位在0bit开始,低位在31bit结束,网络传输时先传输0-7共8个bits,以此类推。

第三,就要说说转换了,其实如果有意义的数据都是一个byte的,那就没必要转化了。但是根据协议,IP数据报长度、校验和等都是占两字节的数字,而TCP的sequence number和acknowledge number是占四字节的数字。这还不算完,这些头里的数字对于网络传递过程中是有意义的,如果你字节序搞错了,协议栈识别时就出错了啊。因此必须把本机字节序转换成网络字节序了。话说回来,如果你在自己传输的数据内容里的数字就无需转换了,网络传输中没有任何程序关注它们,最多是校验。

最后,头分析的时候,按照规范以太帧头13、14两个字节表征类型,0800表示IP数据报,那比较时直接比较就好,没必要想着转换的问题,但是如果你自己编程序填入这个类型时确要注意,如果使用WORD,那就得转换。

 

参考:

http://tech.cncms.com/develop/cjj/95256.html

http://wenku.baidu.com/view/40667e48cf84b9d528ea7a87.html

 

 

 

 

 

 

你可能感兴趣的:(编程,网络,嵌入式,存储,byte,X86)