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

转载 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

大端小端 && 网络字节序

(0)背景: 网络上的数据流是字节流,对于一个多字节数值,在进行网络传输的时候,先传递哪个字节?也就是说,当接收端收到第一个字节的时候,它是将这个字节作为高位还是低位来处理呢?  (1)网...
  • legend050709
  • legend050709
  • 2014-10-08 11:02:13
  • 9661

大端、小端与网络字节序

大端(Big-Endian),小端(Little-Endian)以及网络字节序的概念在编程中经常会遇到,其中网络字节序(Network Byte Order)一般是指大端(Big-Endian,对大部...
  • anningzte
  • anningzte
  • 2016-08-05 08:57:37
  • 6363

c语言客户端与go语言服务端通信(网络字节序)

网络二进制数据转换:      总所周知,数据在tcp网络传输协议中传输的字节序是大端模式的,换句话说如果你要传输一个int32型的整数,那么假设其二进制小端模式表示为111111111111111...
  • whatday
  • whatday
  • 2017-07-14 09:14:19
  • 819

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

一、在进行网络通信时是否需要进行字节序转换?       相同字节序的平台在进行网络通信时可以不进行字节序转换,但是跨平台进行网络数据通信时必须进行字节序转换。      原因如下:网络协议规...
  • yinshitaoyuan
  • yinshitaoyuan
  • 2016-06-29 19:44:03
  • 451

网络字节序和地址转换

1:大小端字节序 参考博文:大小端模式 2:存储字节序和传输字节序 存储字节序:一个多字节的变量在内存中的存储方式,变量的小端数据存储在内存起始位置是小端字节序;变量的大端数据存储在内存起始位置是大端...
  • Golf_research
  • Golf_research
  • 2016-12-21 03:19:28
  • 487

socket网络字节序以及大端序小端序

不同CPU中,4字节整数1在内存空间的存储方式是不同的。4字节整数1可用2进制表示如下: 00000000 00000000 00000000 00000001 有些CPU以上面的顺序存储到内...
  • softn
  • softn
  • 2016-06-02 08:05:21
  • 1451

为什么主机或网络字节序对字符串不影响结果

当进行网络传输时,都要求按照网络字节序进行传输。当接收到结果后,如果我们系统使用的字节序不是网络字节序,那么如果不对整形的结果进行大小端转换,结果就会错误,疑问,为什么字符串的值不受影响?? 思考...
  • woshicheng1990
  • woshicheng1990
  • 2015-07-10 11:52:26
  • 1660

java字节序、主机字节序和网络字节序扫盲贴

java程序员是幸福,因为xiang
  • aitangyong
  • aitangyong
  • 2014-04-08 21:31:54
  • 6840

网络字节序 大端 小端

1.小端法(Little-Endian)就是低位字节排放在内存的低地址端(即该值的起始地址),高位字节排放在内存的高地址端; 2.大端法(Big-Endian)就是高位字节排放在内存的低地址端(即该...
  • happy08god
  • happy08god
  • 2014-10-17 15:55:19
  • 1309

关于字节序、大端、小端、网络字节序

1. 首先最要明确一点:字节顺序是长度跨越多个字节的数据
  • dyzhen
  • dyzhen
  • 2014-11-20 11:04:29
  • 1223
收藏助手
不良信息举报
您举报文章:网络通信时字节序转换原理与网络字节序、大端和小端模式
举报原因:
原因补充:

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