Chinaunix首页 | 论坛 | 博客
  • 博客访问: 590618
  • 博文数量: 50
  • 博客积分: 4764
  • 博客等级: 上校
  • 技术积分: 597
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-18 09:00
个人简介

资深IT码农,擅长Linux、C/C++、bash

文章分类

全部博文(50)

文章存档

2015年(17)

2014年(2)

2011年(7)

2010年(4)

2009年(20)

分类: C/C++

2015-07-23 17:08:19

通过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(或别的方式)将数据还原。
阅读(1323) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~