【问题标题】:Sending a c++ object with vector over socket通过套接字发送带有向量的 c++ 对象
【发布时间】:2013-04-14 08:16:38
【问题描述】:

我已经有很长一段时间试图找到一种通过 tcp 套接字序列化或发送状态对象的好方法。我的问题是我无法使用任何 3. 方库,例如 boost。

我的状态对象包含多个对象。最重要的是它有一些对象和一个对象向量,但没有指针(例如,可能没有深度复制,如果向量不需要这个)。

对于我的问题:由于我不能使用 boost 或任何其他库,那么通过套接字发送带有对象的对象的最佳方法是什么? 我一直在想我可能可以创建一个复制构造函数并将其发送到流中,但我不太确定这样做的后果。

【问题讨论】:

  • 你需要用到的工具叫做(反)序列化。尝试搜索 SO,你会发现很多有用的答案(比如这里:stackoverflow.com/questions/234724/…
  • 是的,我需要序列化对象,但我不能像你提到的链接那样使用像 Boost 这样的库。但在这我想知道如何在不使用上述库的情况下序列化对象的最佳方法:)

标签: c++ sockets serialization


【解决方案1】:

为您的数据类型定义(反)序列化函数。

例如,如果你有类似的东西:

class MyClass
{
public: 
    int field_a;
    int field_b;
    std::string string;
    ...
};
typedef std::vector<MyClass> MyVector;

您可以定义以下内容:

void write(int fd, const MyClass &arg)
{
    // either convert arg to byte array and write it, or write field by field
    // here we write it field by field
    write_int(fd, arg.field_a);
    write_int(fd, arg.field_b);
    write_string(fd, arg.string);
}

void write(int fd const MyVector &arg)
{
    size_t size = arg.size();
    ::write(fd, &size, sizeof(size)); // beware: machine-dependent code
    for (MyVector::const_iterator it = arg.begin(); it != arg.end(); it++)
    {
        write(*it);
    }
}

辅助函数:

void write_int(int fd, int arg)
{
    write(fd, &arg, sizeof(int));
}

void write_string(int fd, const std::string &str)
{
    size_t len = str.length();

    write(fd, &len, sizeof(len)); // string length go first
    write(fd, str.data(), len); // write string data
}

阅读:

MyClass readMC(int fd)
{
    // read MyClass data from stream, parse it
    int f1, f2;
    std::string str;

    read_int(fd, f1);
    read_int(fd, f2);

    read_string(fd, str)

    return MyClass(f1, f2, str);
}

void read(int fd, MyVector &arg)
{
    size_t size;
    size_t i;

    read(fd, &size, sizeof(size)); // read number of elements;
    arg.reserve(size);
    for (i = 0; i < size; i++)
    {
        arg.push_back(readMC(fd));
    }
}

辅助函数:

void read_int(int fd, int &res);
{
    read(fd, &res, sizeof(res));
}

void read_string(int fd, std::string &string)
{
    size_t len;
    char *buf;

    read(fd, &len, sizeof(len));
    buf = new char[len];
    read(fd, buf, len);
    string.asssign(buf, len);
    delete []buf;
}

【讨论】:

  • 这听起来像是一个计划,但我对您的代码有一些疑问。 int fd 是什么?你说我可以将 arg 转换为字节数组或逐个字段。我将如何在写入函数中执行此操作,以便我可以在读取时解析它。有没有一种好方法可以将其输出为像 ostream 一样?
  • fd是一个文件描述符,用来访问socket连接。
  • @larhauga 这很简单。套接字传输字节。所以你让你的对象看起来像一个字节序列并返回
猜你喜欢
  • 1970-01-01
  • 2013-09-02
  • 2012-03-13
  • 2011-12-23
  • 1970-01-01
  • 2019-04-21
相关资源
最近更新 更多