【问题标题】:Copy a struct inside a byte buffer在字节缓冲区中复制结构
【发布时间】:2016-07-28 19:26:41
【问题描述】:

我有以下结构:

struct sample {
  uint8_t four;
  bool    b;
  uint8_t two;
};

为了发送一个udp数据包,我需要将这些值打包成一个字节:

| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
+---+---+---+---+---+---+---+---+
|     four      | 0 | b |  two  |
+---------------+---+---+-------+

在这个字节中复制结构值的最佳方法是什么?我在这样做之前检查了前提条件,因此在将 uint8_t 值复制到更小的空间时不会丢失任何数据。

【问题讨论】:

    标签: c++ byte buffer memcpy bytebuffer


    【解决方案1】:

    我只想使用一个函数:

    uint8_t pack( const sample &s )
    {
        return ( s.four & 0xF ) | ( s.b << 5 ) | ( ( s.two & 3 ) << 6 );
    }
    

    正如您所说,检查了数据范围,您可以将其简化为:

        return s.four | ( s.b << 5 ) | ( s.two << 6 );
    

    【讨论】:

      【解决方案2】:

      由于您的代码无论如何都不可移植,因此您不妨在这里使用位域:

      struct sample {
        uint8_t four:4;
        bool    empty:1;   
        bool    b:1;
        uint8_t two:2;
      };
      

      我不喜欢位字段,但它们似乎适用于您的情况。

      【讨论】:

      • 不应该empty 出现在b 之前吗?
      • 为什么不便携?
      • 因为你要对 uint8_t 进行实体序列化,而那是不可移植的。
      【解决方案3】:

      您的位顺序以...独特的方式显示。通常当我们用二进制表示值时,低位显示在右侧。只要您在打包和解包数据,您就可以选择您的位顺序。不过要注意网络顺序与系统顺序。虽然每个平台的字节内位顺序都是相同的,但字内字节顺序可以改变。

      您必须了解您的应用程序才能确定打包/拆包是否值得。在每一侧进行更多的计算,并且取决于 UDP 数据包之间的间隔以及每个 UDP 数据包中包含多少数据,这可能不值得。如果您只是想为蜂窝应用程序保存数据,那么,谢谢 :@)

      由于平台/编译器偏执,我总是避免转换布尔值。可以改用 s.b?32:0 之类的东西。

      【讨论】:

      • 我正在尝试创建 CIGI 数据包,标准有很多以这种方式构建的数据包...
      • 抱歉,有点脑残。网络数据包总是这样写的
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-17
      • 1970-01-01
      • 2012-07-17
      • 2010-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多