0

假设我们正在使用 UDP 套接字编写 C++ 网络应用程序。我们需要传递一个不那么小的数据包,所以我们使用了这种结构,确保字节顺序是网络顺序:

struct [[gnu::packed]] datagram {
    uint64_t timestamp;
    uint8_t type;
    uint32_t temperatures[60]; // whatever, just an example
    uint8_t raw_data[];
};

我们使用的是 GNU GCC,因此我们利用了非标准 C++ 功能,例如

  • 灵活的数组成员
  • 堆积结构

我们需要一个打包的结构,因为我们不希望在两者之间进行填充,因为这可能依赖于架构,并且我们的网络程序可能运行在不同的架构上。

然后,一年后,我们可能需要支持一个非 GCC 编译器,它不支持这些。

是否可以在标准 C++ 中执行此操作?

当然,我知道我们可以简单地uint8_t buffer[SOME_SIZE]对数据报的每个部分使用 a 和 memcpy,但这听起来是创建可怕、非常丑陋的代码的好方法。

4

1 回答 1

3

[[gnu::packed]]在任意架构之间进行序列化是一种糟糕的方式。那里仍然有大端机器。

这样做的正确方法是根据八位字节定义序列化格式,然后在八位字节流(到或来自 UDP 套接字)和排列良好的结构之间进行转换。

有许多库可以使这变得简单。我们protobuf在工作中使用;以前的雇主有一个自制的解决方案。(请注意,对此类库的推荐请求对于 Stack Overflow 来说是明确的题外话。)

于 2017-05-18T14:29:57.070 回答