序列化、字节对齐、字节序(C++)

来源:互联网 发布:矩阵的计算方法 编辑:程序博客网 时间:2024/05/29 08:18

记录下自己对这3个问题的理解,C++编程方式下

字节对齐,存在的意义:是因为C++下,写网络协议的时候,经常写成struct或类class,类似于下边

  1. struct _arp{  
  2.        unsigned short      arp_hrd;  
  3.        unsigned short      arp_pro;  
  4.        unsigned char       arp_hlen;  
  5.        unsigned char       arp_plen;  
  6.   
  7.        unsigned short      arp_op;  
  8.        /*以上以四字节对齐,刚好8个字节......*/  
  9.   
  10.        unsigned char       arp_hrdsrc[6];  
  11.        /*因为后面的跟的是unsigned long,所以以4字节对齐,arp_hrdsrc 实际占了 8 字节*/  
  12.        unsigned long       arp_prosrc;  
  13.        unsigned char       arp_hrddest[6]; /* 8 bytes*/  
  14.        unsigned long       arp_prodest;  
  15. };  

因为经常将网络传输来的数据,直接赋值给类似的struct或类class。类似于

             

  CAsyncRecv asyncRecv(&io_Ntp, &_socket);  boost::system::error_code ec;  std::size_t len = asyncRecv.receive(boost::asio::buffer(arrRecv), boost::posix_time::seconds(5), ec);  _arp resonpse;  std::stringstream strRss;
 strRss.write(reinterpret_cast<const char*>(pBytes), len);  strRss >> resonpse;
这种情况下就需要注意“字节对齐”问题。

然尔序列化后,所有的东西都保存在存储为char的容器中,只要反序列化,就能得到正确的类class或struct。

类似于存储在 std::vector<char > CSerializeData;


问题二:字节序问题,网络字节序和本机字节序

网络(TCP,UDP等),会把你本地的数据按字节一个一个发送到目的端,字节之间的顺序是不会变的。

所以本机字节序和网络字节序不同,也不影响传输。

但本机字节序与目的端字节序不同,就需要在本机或目的机器上,进行字节序的转换。(这里的转换是非char的数据类型为单位的,比如int等)。

相同字节序的平台在进行网络通信时可以不进行字节序转换,但是跨平台进行网络数据通信时必须进行字节序转换。
原因如下:网络协议规定接收到得第一个字节是高字节,存放到低地址,所以发送时会首先去低地址取数据的高字节。小端模式的多字节数据在存放时,低地址存放的是低字节,而被发送方网络协议函数发送时会首先去低地址取数据(想要取高字节,真正取得是低字节),接收方网络协议函数接收时会将接收到的第一个字节存放到低地址(想要接收高字节,真正接收的是低字节),所以最后双方都正确的收发了数据。而相同平台进行通信时,如果双方都进行转换最后虽然能够正确收发数据,但是所做的转换是没有意义的,造成资源的浪费。而不同平台进行通信时必须进行转换,不转换会造成错误的收发数据,字节序转换函数会根据当前平台的存储模式做出相应正确的转换,如果当前平台是大端,则直接返回不进行转换,如果当前平台是小端,会将接收到得网络字节序进行转换。

具体参照:http://blog.csdn.net/songjinshi/article/details/6787762

原创粉丝点击