通过socket传送数据结构
在不同架构的机器之间通过socket传送数据结构时需要注意几个问题:
1. 大小端的问题(Big-Endian 和 Little-Endian)。
x86都是Little-Endian,MIPS和ARM则有可能是Little-Endian或者Big-Endian。
同一个整型数据,在Little-Endian和Big-Endian的机器上,存储的字节顺序是不同的。
解决办法是,发送端将整型数据转换成网络字节序(Big-Endian),然后接收端再将整型数据转换成本地字节序(和系统架构有关)。使用到的函数如下:
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
2. 内置数据类型的长度问题
不同的机器字长和OS类型,可能会导致数据类型的长度不同。以Linux为例,在32-bit x86系统上,long的长度是32-bit;在64-bit x86系统上,long长度则是64-bit。(OS也可能导致数据类型长度不同。64-bit Linux采用LP64标准,而64-bit Windows则采用LLP64标准;两者之间的差别在于long型数据的长度,64-bit Linux上long是64-bit,而64-bit Windows则是32-bit)
解决办法是,使用编译器提供的固定长度的类型,比如: uint16_t,uint32_t,uint64_t等。
3. 数据对齐问题(padding 和 alignment)
以下面的数据结构为例:
struct myPacket {
int a;
double b;
char c;
int d;
char e[80];
};
以Linux为例,如果采用8-byte对齐,得到下面的结果(在32位或64位的x86机器上,gcc等常用编译器默认都是8-byte对齐):
- 4 byte integer
- 4 byte padding
- 8 byte double
- 1 byte character
- 3 byte padding
- 4 byte integer
- 80 characters
如果采用4-byte对齐,那么得到下面的结果:
- 4 byte integer
- 8 byte double
- 1 byte character
- 3 byte padding
- 4 byte integer
- 80 characters
解决办法是,使用C编译器提供的预编译指令来强制对齐,比如: #pragma pack(1) 。
4. 浮点数的表示问题
通常情况下,浮点数都是采用IEEE 754标准的格式存储。但是不能保证没有特殊情况。
解决办法是,将浮点数转换成整型或者字符串来处理。
解决方案:
1. 采用 XDR (External Data Representation, RFC1014),RPC使用的就是这种方法。
2. 采用 Google 的 protocol buffer
3. 发送端用sprintf将每一个数据成员转换成字符数组(字符串),并在数据成员之间加入分隔符。接收端用scanf(或别的方式)将数据还原。
阅读(1400) | 评论(0) | 转发(0) |