一:大小端
(一)大小端区别(字节)
区别是依据:计算机系统在存储数据时起始地址是高地址仍是低地址。
小端:从低地址开始存储
大端:从高地址开始存储
补充:这里大小端是按字节区别的,还有按字的。按字节,则字节大小数据不会改变数据格式,因此如上图中小端“1”,和大端“1”是同样存储的
补充:在内存中存储数据仍是从低地址开始寻址,找到一块空间分配之后,根据大小端区别向内部填充数据
(二)代码实现对大小端的判断
#include #include
using namespacestd;boolbigCheck()
{
union Check{//起始地址是一致的
chara;
uint32_t data;
};
Check c;
c.data= 1;if(1==c.a){return false;
}return true;
}int main(int argc,char*argv[])
{if(bigCheck()){
cout<
}else{
cout<
}return 0;
}
1.选取内存空间
2.大端存放数据
3.小端存放数据
输出结果:
二:本地系统与网络中的大小端问题
(一)本地操做系统与网络字节序
1.本地字节序
不一样操做系统可能会采用不一样的字节序,因此当通讯双方字节序不一样时须要考虑字节序转化问题ios
2.网络字节序
为了不在网络通讯中引入其余复杂性,网络字节序统一是大端的编程
(二)序列化与反序列化
任何变量,无论是堆变量仍是栈变量都对应着操做系统中的一块内存,因为内存对齐的要求程序中的变量并非紧凑存储的,例如一个c语言的结构体Test在内存中的布局可能以下图所示。网络
1.序列化:经过将计算机语言中的内存对象转换为网络字节流,例如把c语言中的结构体Test转化成uint8_t data[6]字节流。
2.反序列化:将网络字节流转换为计算机语言中的内存对象,例如把uint8_t data[6]字节流转化成c语言中的结构体Test。
经过序列化能够使得网络传输获得数据量更少,经过反序列化使得数据接受时格式与原来一致。函数
三:网络编程中的一点小疑惑
(一)前面提到本地字节序和网络字节序(大小端)不一样,那么如何转换??
htonl()--"Host to Network Long"ntohl()--"Network to Host Long"htons()--"Host to Network Short"ntohs()--"Network to Host Short"
以上4种函数实现了对16位、32位数据的网络到本地、本地到网络的转换。布局
补充:数字所占位数小于或等于一个字节(8 bits)时,不要用htons转换。这是由于对于主机来讲,大小端的最小单位为字节(byte)
(二)本地到网络中的哪些数据须要转换??(重点)
不是全部从本地传输到网络中的数据都须要进行大小端的转换!!!
咱们只须要将IP网络层须要访问的数据转化为大端模式,这样网络才知道如何传递、转发数据。而这些数据是指IP地址和端口,IP网络层须要根据这些信息进行转发。ui
IP为网络层,使用的是大端字节序,在IP层中要读取TCP头部中的信息,以肯定要访问的地址。
因此要将port,ip等将在网络层被读取的信息转为大端字节序。
而发送的具体信息,并不被网络层所读取(只是传输),所以只要保证接受方与发送发使用的字节序相同,就不须要进行转换