网络通信时字节序转换原理与网络字节序、大端和小端模式

转载 2012年03月30日 13:44:55

自:http://blog.csdn.net/songjinshi/article/details/6787762

引言:在进行网络通信时是否需要进行字节序转换? 

相同字节序的平台在进行网络通信时可以不进行字节序转换,但是跨平台进行网络数据通信时必须进行字节序转换。
原因如下:网络协议规定接收到得第一个字节是高字节,存放到低地址,所以发送时会首先去低地址取数据的高字节。小端模式的多字节数据在存放时,低地址存放的是低字节,而被发送方网络协议函数发送时会首先去低地址取数据(想要取高字节,真正取得是低字节),接收方网络协议函数接收时会将接收到的第一个字节存放到低地址(想要接收高字节,真正接收的是低字节),所以最后双方都正确的收发了数据。而相同平台进行通信时,如果双方都进行转换最后虽然能够正确收发数据,但是所做的转换是没有意义的,造成资源的浪费。而不同平台进行通信时必须进行转换,不转换会造成错误的收发数据,字节序转换函数会根据当前平台的存储模式做出相应正确的转换,如果当前平台是大端,则直接返回不进行转换,如果当前平台是小端,会将接收到得网络字节序进行转换。
 
下面对一些概念做下介绍:

 

一、大端、小端
"大端"和"小端"表示多字节值的哪一端存储在该值的起始地址处;小端存储在起始地址处,即是小端字节序;大端存储在起始地址处,即是大端字节序;
或者说:
1.小端法(Little-Endian)就是低位字节排放在内存的低地址端(即该值的起始地址),高位字节排放在内存的高地址端;
2.大端法(Big-Endian)就是高位字节排放在内存的低地址端(即该值的起始地址),低位字节排放在内存的高地址端;
举个简单的例子,对于整型数据0x12345678,它在大端法和小端法的系统中,各自的存放方式如下图1所示:


二、网络字节序
网络上传输的数据都是字节流,对于一个多字节数值,在进行网络传输的时候,先传递哪个字节?也就是说,当接收端收到第一个字节的时候,它将这个字节作为高位字节还是低位字节处理,是一个比较有意义的问题;
UDP/TCP/IP协议规定:把接收到的第一个字节当作高位字节看待,这就要求发送端发送的第一个字节是高位字节;而在发送端发送数据时,发送的第一个字节是该数值在内存中的起始地址处对应的那个字节,也就是说,该数值在内存中的起始地址处对应的那个字节就是要发送的第一个高位字节(即:高位字节存放在低地址处);由此可见,多字节数值在发送之前,在内存中因该是以大端法存放的;
所以说,网络字节序是大端字节序;
比如,我们经过网络发送整型数值0x12345678时,在80X86平台中,它是以小端发存放的,在发送之前需要使用系统提供的字节序转换函数htonl()将其转换成大端法存放的数值;如下图2所示:

三、字节序测试
不同CPU平台上字节序通常也不一样,下面这个简单的代码可以测试不同平台上的字节序:
#include <stdio.h>
#include <netinet/in.h>
int main(int argc,char** argv)
{
  int num = 0x12345678;
  unsigned char* pc = (unsigned char*)(&num);
  printf("local order:\n");
  printf("[0]: 0x%X addr:%u\n", pc[0], &pc[0]);
  printf("[1]: 0x%X addr:%u\n", pc[1], &pc[1]);
  printf("[2]: 0x%X addr:%u\n", pc[2], &pc[2]);
  printf("[3]: 0x%X addr:%u\n", pc[3], &pc[3]);
  num = htonl(num);
  printf("htonl order:\n");
  printf("[0]: 0x%X addr:%u\n", pc[0], &pc[0]);
  printf("[1]: 0x%X addr:%u\n", pc[1], &pc[1]);
  printf("[2]: 0x%X addr:%u\n", pc[2], &pc[2]);
  printf("[3]: 0x%X addr:%u\n", pc[3], &pc[3]);
  return 0;
}
SPARC平台上的输出:
local order:
[0]: 0x12 addr:4290770212 //高位字节存放在低地址处,则是大端法;
[1]: 0x34 addr:4290770213
[2]: 0x56 addr:4290770214
[3]: 0x78 addr:4290770215 //低位字节存放在高地址处;
htonl order:
[0]: 0x12 addr:4290770212 //由此看出,主机字节序与网络字节一样;
[1]: 0x34 addr:4290770213
[2]: 0x56 addr:4290770214
[3]: 0x78 addr:4290770215
X86平台上的输出:
local order:
[0]: 0x78 addr:4289157020 //低位字节存放在低地址处,则是小端法;
[1]: 0x56 addr:4289157021
[2]: 0x34 addr:4289157022
[3]: 0x12 addr:4289157023 //高位字节存放在高地址处;
htonl order:
[0]: 0x12 addr:4289157020 //由此看出,主机字节序与网络字节不一样;
[1]: 0x34 addr:4289157021
[2]: 0x56 addr:4289157022
[3]: 0x78 addr:4289157023
INTEL平台上的输出:
local order:
[0]: 0x78 addr:1245044    //低位字节存放在低地址处,则是小端法;
[1]: 0x56 addr:1245045
[2]: 0x34 addr:1245046
[3]: 0x12 addr:1245047    //高位字节存放在高地址处;
htonl order:
[0]: 0x12 addr:1245044    //由此看出,主机字节序与网络字节不一样;
[1]: 0x34 addr:1245045
[2]: 0x56 addr:1245046
[3]: 0x78 addr:1245047

网络通信时字节序转换原理与网络字节序、大端和小端模式

引言:在进行网络通信时是否需要进行字节序转换?  相同字节序的平台在进行网络通信时可以不进行字节序转换,但是跨平台进行网络数据通信时必须进行字节序转换。 原因如下:网络协议规定接收到得第一个字节是...

网络通信之 字节序转换原理与网络字节序、大端和小端模式

一、在进行网络通信时是否需要进行字节序转换?       相同字节序的平台在进行网络通信时可以不进行字节序转换,但是跨平台进行网络数据通信时必须进行字节序转换。      原因如下:网络协...

网络通信之 字节序转换原理与网络字节序、大端和小端模式

一、在进行网络通信时是否需要进行字节序转换? 相同字节序的平台在进行网络通信时可以不进行字节序转换,但是跨平台进行网络数据通信时必须进行字节序转换。 原因如下:网络协议规定接收到得第一个字节是高字...
  • yfgcq
  • yfgcq
  • 2016年07月19日 18:03
  • 712

网络通信之 字节序转换原理与网络字节序、大端和小端模式

转自:http://www.cnblogs.com/fuchongjundream/p/3914770.html 一、在进行网络通信时是否需要进行字节序转换?       相同字节序的...

网络字节:大端和小端的判别及转换

当前的存储器,多以byte为访问的最小单元,当一个逻辑上的地址必须分割为物理上的若干单元时就存在了先放谁后放谁的问题,于是端(endian)的问题应运而生了,对于不同的存储方法,就有大端(big-en...
  • zs10hz
  • zs10hz
  • 2014年10月16日 10:37
  • 282

大端模式、小端模式与网络字节序

1.概述 2,.判断方法 3.

大端模式小端模式以及网络字节序

主机字节序有两种:大端模式和小端模式 大端模式:高字节存放在低地址,低字节存放在高地址; 小端模式:低字节存放在低地址,高字节存放在高地址; 不同的CPU有不同的主机字节序类型。 Ø  典型的...

字节序有大端和小端之分

(1)对于位域结构中的变量来说,其长度不能跨越字节,也就是说不能超过8位。当然如果设置空白位(无名变量,仅仅用作占位的)是没有这个限制的。如果一个字节剩下的位长度不够一个位域,那么从下个字节开始,也可...

linux大端,小端,网络字节序转换之可移植性代码

我们有时候经常被大端,小端,网络字节序搞得很迷糊,本文理清一些概念,并给出可移植的代码。 我们的主机字节序,即我们的机器存放内存里的顺序,有两种,一种是大端,另一种是小端,大部分的系统都是小端。 ...

网络通讯中的字节序转换及大端、小端

一、在进行网络通信时是否需要进行字节序转换? 相同字节序的平台在进行网络通信时可以不进行字节序转换,但是跨平台进行网络数据通信时必须进行字节序转换。 原因如下:网络协议规定接收到得...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:网络通信时字节序转换原理与网络字节序、大端和小端模式
举报原因:
原因补充:

(最多只允许输入30个字)