socket通信中的大小端问题及解决措施

本人一直有个疑惑,大小端通信怎么存储(以前一直知道这个概念,但怎么都跟实际匹配不上,网络上也并没有说怎么处理大小端通信问题)

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

posted @ 2024-09-23 10:49  川西神往  阅读(293)  评论(0)    收藏  举报