什么时候需要转网络序?
在计算机中存储数据的字节次序也是不同的,有的是把低位字节放在低位地址,称为小端法,有的把高位字节放在低位地址,称为大端法,所以同一个数字,在不同计算机内存储的字节次序是会不同的,假设两台计算机使用不同的方法存储同一个数字,那么当从一台计算机把数据通过网络发到另一台计算机时,如果接收数据的计算机还是按照发送数据的计算机的数据读取数据,那么就会出现错误,所以出现了一项规定,也就是当服务端数据发送到网络后,把数据次序都转换成一样的字节次序,等数据到达客户端时,再把数据字节次序转换成客户端存储字节的方式,这样数据就不会出现错误了字节序是由于不同的主处理器和操作系统,对大于一个字节的变量在内存中的存放顺序不同而产生的。
有两种处理内存中数据的方法:大端格式、小端格式。
1. 实际需求
(1) 前段时间写了一个修复损坏的gzip文件的tool,在Linux Server上编译运行没有问题。但是在Solaris Server上运编译运行,结果总是和预期的不一致,跟踪发现是由大小端问题导致的;
(2) 最近在写一个跨平台的编译脚本,编译参数里有目标可执行程序运行平台大小端这个参数;
2. 大小端解析
端模式出自Jonathan Swift书写的《格列佛游记》一书,这本书根据将鸡蛋敲开的方法不同将所有的人分为两类,从圆头开始将鸡蛋敲开的人被归为Big Endian,从尖头开始将鸡蛋敲开的人被归为Littile Endian。小人国的内战就源于吃鸡蛋时是究竟从大头(Big-Endian)敲开还是从小头(Little-Endian)敲开。
在计算机业Big Endian和Little Endian也几乎引起一场战争。在计算机业界,Endian表示数据在存储器中的存放顺序。
大端:高位存在低地址,低位存在高地址;
小端:高位存在高地址,低位存在低地址;(intel的x86,ARM普遍都是属于小端)
举个例子,从内存地址0x0000开始有以下数据
0x0000 0x12
0x0001 0x34
0x0002 0xab
0x0003 0xcd
如果我们去读取一个地址为0x0000的四个字节变量:
若字节序为big-endian,则读出结果为0x1234abcd;
若字节序位little-endian,则读出结果为0xcdab3412.
如果我们将0x1234abcd写入到以0x0000开始的内存中,则结果为:
big-endian little-endian
0x0000 0x12 0xcd
0x0001 0x23 0xab
0x0002 0xab 0x34
0x0003 0xcd 0x12
#include <stdio.h>
#include <sys/types.h>
main()
{
int x=0x12345678; /* 305419896 */
unsigned char *p=(char *)&x;
printf("%0x % 0x %0x %0x",p[0],p[1],p[2],p[3]);
}
输出:78 56 34 12
说明是小端!反过来的则是大端
本文转自 Linux_woniu 51CTO博客,原文链接:http://blog.51cto.com/linuxcgi/1965272