通过UDP发送Struct

时间:2016-05-26 12:03:04

标签: c++ networking struct qudpsocket

我想通过QUdpSocket发送一个结构。 我知道我应该使用QDataStreamQByteArray,但我不能,因为接收器不会使用Qt。

我尝试了很多东西,但我从来没有找到似乎正在做的工作正确

我的结构将是:

typedef struct myStruct
    {
       int nb_trame;
       std::vector<bool>  vBool;
       std::vector<int>   vInt;
       std::vector<float> vFloat;
    } myStruct;

我如何正确正确

1 个答案:

答案 0 :(得分:3)

对此的解决方案称为serialization

  

序列化是将数据结构或对象状态转换为可以存储的格式(例如,在文件或内存缓冲区中,或通过网络连接链接传输)并稍后在相同或另一个计算机环境中重建的过程

以下是如何使用QDataStream序列化所提到的结构的完整工作示例:

// main.cpp
#include <limits>
#include <QDataStream>
#include <QVector>
#include <vector>

typedef struct myStruct
{
   int nb_trame;
   std::vector<bool>  vBool;
   std::vector<int>   vInt;
   std::vector<float> vFloat;

   void serialize(QDataStream &out) {
       out << nb_trame;
       out << QVector<bool>::fromStdVector(vBool);
       out << QVector<qint32>::fromStdVector(vInt);
       out << QVector<float>::fromStdVector(vFloat);
   }
} myStruct;

void fillData(myStruct &s) {
    s.nb_trame = 0x42;

    s.vBool.push_back(true);
    s.vBool.push_back(false);
    s.vBool.push_back(false);
    s.vBool.push_back(true);

    s.vInt.push_back(0xB0);
    s.vInt.push_back(0xB1);
    s.vInt.push_back(0xB2);
    s.vInt.push_back(0xB3);

    s.vFloat.push_back(std::numeric_limits<float>::min());
    s.vFloat.push_back(0.0);
    s.vFloat.push_back(std::numeric_limits<float>::max());
}

int main()
{
    myStruct s;

    fillData(s);

    QByteArray buf;
    QDataStream out(&buf, QIODevice::WriteOnly);
    s.serialize(out);
}

然后,您可以使用buf

发送QUdpSocket::writeDatagram()

QDataStream如何序列化

如果我们更换

QByteArray buf;
QDataStream out(&buf, QIODevice::WriteOnly);

QFile file("file.dat");
file.open(QIODevice::WriteOnly);
QDataStream out(&file);

序列化数据被写入文件“file.dat”。这是上面代码生成的数据:

> hexdump -C file.dat
00000000  00 00 00 42 00 00 00 04  01 00 00 01 00 00 00 04  |...B............|
00000010  00 00 00 b0 00 00 00 b1  00 00 00 b2 00 00 00 b3  |................|
00000020  00 00 00 03 38 10 00 00  00 00 00 00 00 00 00 00  |....8...........|
00000030  00 00 00 00 47 ef ff ff  e0 00 00 00              |....G.......|
  • 数据以表示成员nb_trame(00 00 00 42
  • 的四个字节开头
  • 接下来的八个字节是向量vBool(00 00 00 04 01 00 00 01)的序列化形式
    • 00 00 00 04 - &gt;向量中的条目数
    • 01 00 00 01 - &gt;真,假,假,真
  • 接下来的20个字节用于vInt(00 00 00 04 00 00 00 b0 00 00 00 b1 00 00 00 b2 00 00 00 b3
    • 00 00 00 04 - &gt;向量中的条目数
    • 00 00 00 b0 00 00 00 b1 00 00 00 b2 00 00 00 b3 - &gt; 0xB0,0xB1,0xB2,0xB3(每个条目4个字节)
  • 接下来的28个字节用于vFloat(00 00 00 03 38 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 47 ef ff ff e0 00 00 00
    • 00 00 00 03 - &gt;向量中的条目数
    • 38 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 47 ef ff ff e0 00 00 00 - &gt; 1.1754943508222875e-38,0.0,3.4028234663852886e + 38(每个条目8个字节)

其他信息(原始发布)

序列化不是一个简单的主题,但有很多库,可以帮助你。最后,您有两个选项可供选择:

  1. 定义您自己的序列化格式
  2. 使用现有的序列化格式
    1. 二进制
    2. 基于文本(例如JSON,XML)
  3. 您选择哪一个取决于您的需求和用例。总的来说,我更喜欢既定的格式而不是自酿。基于文本的格式本质上不那么紧凑,需要更多空间,因此也需要带宽。在决定格式时,您应该考虑这一点。另一方面,基于文本/人类可读的格式具有易于调试的优点,因为您可以在文本编辑器中打开它们。还有更多因素需要考虑。

    序列化的工作原理是因为您不依赖于机器相关的东西。您唯一需要注意的是序列化数据是一致的并遵循定义的格式。因此,对于序列化数据,您确切地知道如何定义字节顺序,存储特定数据的位置等等。

    这个想法是发送者序列化数据,通过任何需要的通道发送数据,接收器再次反序列化数据。数据以哪种格式存储在双方的每一方都没关系。

       +--------------------------------+             +--------------------------------+
       | Host A                         |             | Host B                         |
       |                                |             |                                |
       |                                |             |                                |
       |                                |             |                                |
       |  +-------------------------+   |             |  +-------------------------+   |
       |  |         Raw data        |   |             |  |         Raw data        |   |
       |  |(Specific to plattfrom A)|   |             |  |(Specific to plattfrom B)|   |
       |  +-------------------------+   |             |  +-------------------------+   |
       |               |                |             |               ^                |
       |               | serialize      |             |               | deserialize    |
       |               v                |             |               |                |
       |      +-----------------+       |  transmit   |      +-----------------+       |
       |      | Serialized Data +----------------------------> Serialized Data |       |
       |      +-----------------+       |             |      +-----------------+       |
       |                                |             |                                |
       +--------------------------------+             +--------------------------------+