我想知道是否没有人使用联合来序列化boost :: asio发送器/接收器的结构。我已经搜索了一些东西,但是我发现的所有东西都是像thisthis这样的例子。

所以我这样做是这样的:

struct ST {
  short a;
  long b;
  float c;
  char c[256];
}
...

void sender::send(const ST &_packet) {
  union {
    const ST &s;
    char (&c)[sizeof(ST)];
  }usc = {_packet};

  socket.send_to(boost::asio::buffer(usc.c, sizeof(ST)), endpoint);
}
...

ST var = {1234, -1234, 1.4567, "some text"};
sercer.send(var);


所以我现在的问题是,对基本数据类型进行序列化是一种不好的做法吗?

我知道我不能直接发送var大小的字符串,因此我可以使用boost :: serialization。

最佳答案

这确实是一个坏习惯。您发送的是(假设是)一个字节序列,其中包含系统联合中所包含内容的确切二进制表示形式。问题是:


您用一个ST填充usc联合,但将其作为char []访问,这会产生未定义的行为(但可能在所有通用系统上都有效)。
您可能希望在接收器端以相反的顺序执行相同的操作。 UB再次出现,但可能可行。
麻烦来了:您以系统特定的格式发送数据,对于相同的结构定义,接收方系统上的数据不必相同。这包括

整数类型的字节顺序(小/大字节序)
类型的大小,不仅是整数(例如,sizeof(long)有时在32位和64位系统之间或在64位系统上的不同编译器之间都不同)
填充字节
sizeof(ST)本身可能会有很大差异



简单地说:就是不要这样做。如果仍然使用boost :: serialization,则将其用于整个ST结构,而不仅用于其中的字符串。如果您的数据结构变得稍微复杂一点(例如,包含指针,具有不平凡的构造函数等),则无论如何都必须这样做。

09-10 10:01
查看更多