本人一直有个疑惑,大小端通信怎么存储(以前一直知道这个概念,但怎么都跟实际匹配不上,网络上也并没有说怎么处理大小端通信问题)
socket通信中 addr 需要转换成网络字节序,也就是大端
助记: htonl h-> host 缩写 n -> net 缩写 l 是类型缩写(l -> long ll-> longlong s short 都是无符号的)
首先理解下,大小端 数据在内存的存储顺序不同,注意数据还是那个数据,只是存储的方式不同。
大端,数据的低位在内存的高位
小端,数据的低位在内存的低位
内存地址是按字节排序的 0x01 0x02 每个地址偏移是一个字节的内容。
数据 0x12345678 数据的从低到高 0x78 0x56 0x34 0x12.
大端 内存内数据 0x01-0x12 0x02-0x34 0x03-0x56 0x04-0x78
小端 内存内数据 0x01-0x78 0x02-0x56 0x03-0x34 0x04-0x12
socket传输的是字节流,byte[] 数组,我们分两种情况讨论 unsigned int var=0x12345678; 在网络中的传输状态。
1.两端 大小端 一致,则直接使用memcpy就可以,memcpy是内存数据的 大端会变成 0x12345678 数据传输到对端,把数据copy到内存中也是 0x12345678, 小端是 0x78563412, copy 到本地 也是这个值,毫无影响。
2.两端 大小端 不一致,变成byte数据的时候,memcpy是内存数据的 大端会变成 0x12345678 数据传输到对端,把数据copy到内存中也是 0x12345678, 这时cpu按内存地址认为值的话, 并不等于 数据0x12345678. 所以解析错误。小端同理。
解决办法,所以在socket传输多字节数据的情况下,需要把内存数据转为数据顺序(自定义的,可以从高到低,也可以从低到高,但是发送端和解析端必须一致)
1 char * writeInt32(int v) { 2 char *buf = new char[4]; 3 buf[0] = (v >> 24) & 0xFF; 4 buf[1] = (v >> 16) & 0xFF; 5 buf[2] = (v >> 8) & 0xFF; 6 buf[3] = (v >> 0) & 0xFF; 7 8 return buf; 9 }
1 int readInt32(char[] buf) { 2 int ch1 = buf[0]; 3 int ch2 = buf[1]; 4 int ch3 = buf[2]; 5 int ch4 = buf[3]; 6 return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0)); 7 }
通过上述write32()和readInt32()之后,每次接收方或者发送方都以byte字节进行读写,就可以保证socket两端数据保持一致性,避免了大小端问题。
【补充】
大小端出现的原因:两台设备之间的cpu架构不同,导致数据存储时有些设备使用大端存储(PowerPC系列是采用大端存储模式的典型代表。),有些设备采用小端存储(x86系列)
转载至:https://www.cnblogs.com/zijian-yang/p/15821625.html
标签:socket,int,buf,通信,内存,大小,0x12345678,数据 From: https://www.cnblogs.com/xaio-lis/p/18426607