网络字节序与主机字节序

参考:http://www.eygle.com/digest/2007/01/whats_mean_endian.html

http://zhidao.baidu.com/question/43793821.html

http://blog.chinaunix.net/u1/53855/showart_1836894.html

 

网络字节序与主机字节序

不同的CPU有不同的字节序类型 这些字节序是指整数在内存中保存的顺序 这个叫做主机序
最常见的有两种
1. Little endian:将低序字节存储在起始地址
2. Big endian:将高序字节存储在起始地址(网络序)

 

实质:将多字节数的哪个字节(高/低字节)放在起始地址。

 

一、引子
  在各种计算机体系结构中,对于字节、字等的存储机制有所不同,因而引发了
计算机通信领域中一个很重要的问题,即通信双方交流的信息单元(比特、字节、
字、双字等等)应该以什么样的顺序进行传送。如果不达成一致的规则,通信双方
将无法进行正确的编/译码从而导致通信失败。目前在各种体系的计算机中通常采
用的字节存储机制主要有两种:big-edian和little-endian。

二、endian的由来
  1、Definition
  endian: The ordering of bytes in a multi-byte number.
定义:在计算机系统体系结构中用来描述在多字节数中各个字节的存储顺序。

三、各种endian
  1、big-endian
  A computer architecture in which, within a given multi-byte numeric
representation, the most significant byte has the lowest address (the
word is stored "big-end-first").  
Most processors, including the IBM 370 family, the PDP-10, the
Motorola microprocessor families, and most of the various RISC designs
current in mid-1993, are big-endian. [From: Free On-Line Dictionary Of
Computing or Jargon File]
  big-endian:计算机体系结构中一种描述多字节存储顺序的术语,在这种机制
中最重要字节(MSB)存放在最低端的地址上。采用这种机制的处理器有IBM3700系
列、PDP-10、Mortolora微处理器系列和绝大多数的RISC处理器。

 

+----------+
| 0x34 |<-- 0x00000021
+----------+
| 0x12 |<-- 0x00000020
+----------+
图1:双字节数0x1234以big-endian的方式存在起始地址0x00000020中

 

  在Big-Endian中,对于bit序列中的序号编排方式如下(以双字节数0x8B8A为
例):
bit 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+----------------------------------------+
val | 1 0 0 0 1 0 1 1 | 1 0 0 0 1 0 1 0 |
+----------------------------------------+
^ 0x8B 0x8A ^
MSB LSB
图2:Big-Endian的bit序列编码方式

 

  注1:通常在TCP/IP协议栈所说的网络序(Network Order)就是遵循Big-Endian
规则。在TCP/IP网络通信中,通信双方把消息按照如图2的方式进行编码,然后按
从MSB(Bit0)到LSB的顺序在网络上传送。
  2、little-endian
   A computer architecture in which, within a given
16- or 32-bit word,bytes at lower addresses have lower significance (the
word is stored "little-end-first"). The PDP-11 and VAX families of
computers and Intel microprocessors and a lot of communications and
networking hardware are little-endian.
  The term is sometimes used to describe the ordering of units other
than bytes; most often, bits within a byte. [From: Free On-Line Dictionary
Of Computing or Jargon File]
  little-endian:计算机体系结构中一种描述多字节存储顺序的术语,在这种机
制中最不重要字节(LSB)存放在最低端的地址上。采用这种机制的处理器有PDP-11、
VAX、Intel系列微处理器和一些网络通信设备。该术语除了描述多字节存储顺序外
还常常用来描述一个字节中各个比特的排放次序。

 

+----------+
| 0x12 |<-- 0x00000021
+----------+
| 0x34 |<-- 0x00000020
+----------+
  图3:双字节数0x1234以little-endian的方式存在起始地址0x00000020中

 

  在Little-Endian中,对于bit序列中的序号编排和Big-Endian刚好相反,其方
式如下(以双字节数0x8B8A为例):

 

bit 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-----------------------------------------+
val | 1 0 0 0 1 0 1 1 | 1 0 0 0 1 0 1 0 |
+-----------------------------------------+
^ 0x8B 0x8A ^
MSB LSB
图4:Little-Endian的bit序列编码方式

 

  注2:通常我们说的主机序(Host Order)就是遵循Little-Endian规则。所以
当两台主机之间要通过TCP/IP协议进行通信的时候就需要调用相应的函数进行主机
序(Little-Endian)和网络序(Big-Endian)的转换。
注3:正因为这两种机制对于同一bit序列的序号编排方式恰恰相反,所以《现
代英汉词典》中对MSB的翻译为"最高有效位"欠妥,故本文定义为"最重要的bit
/byte"。

 

  3、middle-endian:
   Neither big-endian nor little-endian. Used of
perverse byte orders such as 3-4-1-2 or 2-1-4-3, occasionally found in
the packed decimal formats of some minicomputer manufacturers.[From:
Free On-Line Dictionary Of Computing or Jargon File]
  middle-endian:除了big-endian和little-endian之外的多字节存储顺序就是
middle-endian,比如以4个字节为例:象以3-4-1-2或者2-1-4-3这样的顺序存储的
就是middle-endian。这种存储顺序偶尔会在一些小型机体系中的十进制数的压缩格
式中出现。

 

4 判断主机字节序

首先我们需要知道什么是小端字节序和大端字节序。

   考虑一个16位整数,它由2个字节组成。内存中存储这两个字节有两种方法:一种是将低序字节存储在低地址中,高字节存储在高地址中,这称为小端字节序(little-endian)字节序;另一种是将高序字节存储在低地址中,低序字节存储在高地址中,这称为大端字节序(big-endian).
   其次我们需要知道用union怎么来查到主机的字节序,这就需要明白union的存储结构,那什么是Union呢,联合(union)是一种新的数据类型,它是一种特殊的变量;
   union 联合名{
        数据类型  成员名;
        数据类型  成员名;
        .......
    }联合变量名;
   联合表示几个变量公用一个内存位置,在不同的时间保存不同的数据类型和不同长度的变量。
   例如:

int
main()
{
   union{
         int i;
         struct{
               char first;
               char second;
          }half;
        }number;
   number.i = 0x4241;
   printf("%c%c/n",number.half.first,number.half.second);
   return 0;
}

输出结果:
AB

下面就让我们看看用程序怎么来查看主机的字节序:

#include <stdio.h>
#include <stdlib.h>
int
main()
{
     union{
          short s;
          char c[sizeof(short)];
     }un;
     un.s = 0x0102;
     if(sizeof(short) == 2){
           if(un.c[0] == 1 && un.c[1] == 2)
           printf("big-endian/n");
           else if(un.c[0] == 2 &&un.c[1] == 1)
           printf("little-endian/n");
           else
           printf("unkown");
     }
     exit(0);
}

 

 

你可能感兴趣的:(网络字节序与主机字节序)