最近在项目中的soket通讯时,遇到了大小字节序问题和网络传输时的字节序问题,如今给你们整理一下,但愿你们对字节序有个比较深刻的了解,其实理解了就很简单的。java
一、本地的数据经过网络传输而后在目的地解析网络上的数据,字节序是如何统一的linux
二、字节序不一样,数据(如0xFF00)存入内存地址中位置不一样(大字节序:FF--低地址位 00--高地址位 ;小字节序: 00--低地址位 FF--高地址位),为何读出的值都是0xFF00ios
大字节序:大端有效 ,高位数据先放入低地址内存 , 低位数据放入高地址内存windows
小字节序:小端有效,低位数据先放入低地址内存 , 高位数据再放入高地址内存 数组
注意:描述的是将数据(肉眼看到的)放入内存中的地址(计算机的硬盘内存中)网络
而后看一下图示吧:函数
相信你们对遇到的第二个问题已经知道结果了吧,如今再来看看第一个问题。ui
网络字节序:是大字节序,在把数据进行网络传输时,要保证本身传输到网络上的数据时大字节序。this
再来看看图示吧:spa
1号线路:发数据和接收数据都不须要转序,由于本身是和网络都是大字节序
2号线路:发数据和接收数据都须要转序,由于本身是小字节序,网络都是大字节序,才能保证本身本系统的数据永远都是小字节序。可能高级语言(java、C#屏蔽了字节序,你们感觉不到,那是由于高级语言内存进行封装和处理了)。
补充一下:若是发端和收端都是小字节序,能够不转序,可是这样作可扩展不高,若是收端是大字节序的话,人家默认为发过来的数据都是网络字节序(大字节序),这样处理就很混乱了。
好了,如今你们对第一个问题也清楚了吧。
最后让咱们来看看鉴定大小字节序的C/C++语言程序吧
#include <stdlib.h> #include <string.h> int main() { /*将结合体的整型值赋值为1,若是是小字节序,小端有效,低地址写入的就是1,读出字符ch就是1 若是是大字节序,大端有效,低地址写入的就是0,读出字符ch就是0*/ data.i = 1; if(data.ch) { printf("this system is small-endian\n"); } else { printf("this system is big-endian\n"); } return 0; }
缘由:将结合体的整型值赋值为1,若是是小字节序,小端有效,低地址写入的就是1,读出字符ch就是1
若是是大字节序,大端有效,低地址写入的就是0,读出字符ch就是0
检验大小字节序的方法不少,本人认为这个方法比较简单,容易理解。
重要>>>字节序转化,只是针对二字节、四字节的数据类型,对于单字节和数据区(本质也是单字节的数组)不须要转化。
注意:在使用转序函数时,函数内部会去判断本机字节序,决定要不要转
#include <iostream> using namespace std; /*windows下的头文件;linux下是#include <arpa/inet.h>*/ #include<Winsock2.h> int main(int argc,char *argv[]) { /*经常使用方法(注意,在使用转序函数时,内部会去判断本机字节序,决定要不要转) ****** host(本地)-->net(网络): uint32_t htonl(uint32_t hostlong); uint16_t htons(uint16_t hostshort); ****** net(网络) -->host(本地): uint32_t ntohl(uint32_t netlong); uint16_t ntohs(uint16_t netshort); */ unsigned int srcNum = 0xff; unsigned int netNum = htonl(srcNum); printf("src-->net: srcNum=0x%x netNum=0x%x\n",srcNum,netNum); unsigned int toNum = ntohl(netNum); printf("net-->to : netNum=0x%x srcNum=0x%x \n",netNum,toNum); system("pause"); return 0; }
此代码是在windows环境下编译,若是编译报错:error LNK2019: 没法解析的外部符号 _ntohl@4,缘由是没有引入ws2_32.lib库,只要在 项目->属性->配置属性->连接器->输入 而后在附件依赖项添加ws2_32.lib
一、 IP(无符号整型,如0x80702101)在大、小字节序的系统中的内存是怎么存放的(把这个IP当作4字节的数组unsigned char arry[4],则数组中每一个元素各是多少呢?)提示:数组的下标越大,地址就越大。
小字节:arr[0]=0x01 arr[1]=0x21 arr[2]=0x70 arr[4]=0x80
大字节:arr[0]=0x80 arr[1]=0x70 arr[2]=0x21 arr[4]=0x01
最后但愿能对你们有帮助,有什么问题请留言,谢谢。