通过 ZeroMQ 以字符串形式接收对象然后通过另一个套接字以零副本发送它的正确方法是啥?

Posted

技术标签:

【中文标题】通过 ZeroMQ 以字符串形式接收对象然后通过另一个套接字以零副本发送它的正确方法是啥?【英文标题】:What is the correct way to receive an object as a string through ZeroMQ and then send it with zero-copy through another socket?通过 ZeroMQ 以字符串形式接收对象然后通过另一个套接字以零副本发送它的正确方法是什么? 【发布时间】:2016-08-01 13:01:51 【问题描述】:

我正在使用ZeroMQ 接收一个大型的序列化二进制对象:

std::unique_ptr<Message> input(CreateMessage());

if (Receive(input, "data") > 0) 
    std::string serialStr(static_cast<char*>(input->GetData()), input->GetSize());

如何通过另一个套接字发送这个对象,避免不必要的 memcpy:

std::unique_ptr<Message> output(CreateMessage(serialStr.length()));
memcpy(output->GetData(), serialStr.c_str(), serialStr.length());

fChannels.at("data2").at(0).Send(output);

另外,使用 std::string 来包含二进制对象是个好主意,还是应该使用 void* 代替?

【问题讨论】:

【参考方案1】:

如果您所做的只是转发,那么您可以使用相同的消息,您可以使用类似的内容:

std::unique_ptr<Message> input(CreateMessage());
if (Receive(input, "data") > 0)

    fChannels.at("data2").at(0).Send(input);

或者,您可以查看 4 参数消息构造函数,以使用现有缓冲区作为消息负载而不是复制。

【讨论】:

如果我想先检查消息(即反序列化它)并仅在它符合特定条件时转发它怎么办?在那种情况下我还能转发收到的消息吗?另外,在上面的代码示例中,我猜你的意思是 fChannels.at("data2").at(0).Send(input); 我确实做到了。从缓冲区创建 std::string 将制作副本并保持消息不变,这样就可以了。不过有一个警告,在Send 调用之后的某个时间点,input 的内容将被 zeromq 删除/释放,所以在此之前制作你的字符串。

以上是关于通过 ZeroMQ 以字符串形式接收对象然后通过另一个套接字以零副本发送它的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

使用 ZeroMQ 实现消息总线

如何通过 Android 设备创建的 WiFi 直接网络在 iOS 中使用 ZeroMQ 发送/接收消息

如何在 HSQLDB 表列中以字符串形式保存 XML 数据

是否可以向 ZeroMQ 添加事件处理以在接收/发送数据时采取行动?

ajax怎么接收一个List

通过套接字以字符串形式发送数据的好方法是啥?