使用 boost 套接字的 Boost 序列化失败

Posted

技术标签:

【中文标题】使用 boost 套接字的 Boost 序列化失败【英文标题】:Boost serialization with boost socket fails 【发布时间】:2019-05-22 09:36:06 【问题描述】:

我正在尝试对通过 asio 套接字传递的对象进行反序列化,但出现错误: “在抛出 'boost::archive::archive_exception' 的实例后调用终止 什么():输入流错误“ 当我试图获取数据时:

服务器端:

int main()

...
    std::ostringstream oss;
    Note note(20,20);

    boost::archive::text_oarchive oa(oss);
    oa << note;
    std::cout << (char*)&oa << std::endl;
    send_(socket_, (char *)&oa);

客户端:

int main()

...
    boost::asio::read(socket, receive_buffer, boost::asio::transfer_all(), error);

    std::string myString;

    std::istream(&receive_buffer) >> myString;
    std::istringstream iss(myString);
    boost::archive::text_iarchive ia(iss); <--- input stream error
    ia >> note;
    std::cout << note.denominateur << std::endl;

【问题讨论】:

【参考方案1】:

您必须发送 ostringstream 的内容,即包含序列化 Note 的字符串。现在您正在发送 text_oarchive 实例的字节,这对我来说没有任何意义。

它可能看起来像:

  boost::archive::text_oarchive oa(oss);
  oa << note;
  cout << oss.str(); // HERE you get some string which represents serialized Note
  // and content of this string should be sent
  send_(socket_, oss.str().c_str(), oss.str().size());
                 ^^^ content        ^^^ size of content

您的send_ 函数没有大小参数?有趣的是,对我来说,应该用这个参数知道必须传输多少字节。

关于客户端:

// [1]
boost::asio::read(socket, receive_buffer, boost::asio::transfer_all(), error);

因为您没有提供 MCVE,我假设在 [1] 行中您将 receive_buffer 创建为某种 dynamic_buffer,如果没有,它只是空字符串,您将读取空字符串。所以反序列化是行不通的。

【讨论】:

非常感谢。我用 send_ 那种方式: send_(socket_, oss.str().c_str()); boost的send_函数不带size参数 是的,我知道,但是 send_ 在您的代码中使用指向 char* 的指针,在这种情况下,无法推断缓冲区的大小。例如,如果您传递了string,则不会有问题,因为缓冲区的大小等于string.size()。最重要的是现在你的代码可以工作了:)

以上是关于使用 boost 套接字的 Boost 序列化失败的主要内容,如果未能解决你的问题,请参考以下文章

在 boost 中序列化二进制数据失败并出现“无效签名”错误

std::vector<float> 成员的 boost 序列化/反序列化失败

在 Boost.Asio 中同时使用 SSL 套接字和非 SSL 套接字?

使用 boost io_service 初始化 boost udp 套接字时出错

使用 boost::asio 获取 UDP 套接字远程地址

我们可以用 boost.asio 创建未命名的套接字来模拟匿名管道吗?