C++11 如果设置protobuf可序列化类的值,为什么会出现zmq错误?

C++11 如果设置protobuf可序列化类的值,为什么会出现zmq错误?,c++11,protocol-buffers,zeromq,C++11,Protocol Buffers,Zeromq,我正在测试一段代码,它使用zmq作为套接字和网络工具,使用protobuf进行序列化 代码接收zmq_消息并将其解析为protobuf类,作为回报,我更改一个类成员的值并将同一个类发送回请求者 不知何故,在此过程中,zmq断言检查失败。我真的不知道为什么会这样,因为我觉得一切都很好 主文件中的代码如下所示: zmq::socket_t external(context, ZMQ_REP); external.bind("tcp://*:29067"); zmq::message_t reque

我正在测试一段代码,它使用zmq作为套接字和网络工具,使用protobuf进行序列化

代码接收zmq_消息并将其解析为protobuf类,作为回报,我更改一个类成员的值并将同一个类发送回请求者

不知何故,在此过程中,zmq断言检查失败。我真的不知道为什么会这样,因为我觉得一切都很好

主文件中的代码如下所示:

zmq::socket_t external(context, ZMQ_REP);
external.bind("tcp://*:29067");

zmq::message_t request;
external.recv(&request);
msg.deserialize(request);

msg.set_probed_value(12.0);
zmq::message_t response = msg.serialize();
external.send(response);
反序列化方法如下所示

_msg.ParseFromString(reinterpret_cast<const char*>(msg.data()));
我知道,当我将prospected的值设置为与解析时设置的值不同的数字时,问题就产生了。如果我删除msg.set\u prospected\u value12.0这一行,就不会发生异常,一切都正常

断言失败:check/apps/zmq/libzmq/src/msg.cpp:347

嫌疑犯?违反ZeroMQ API发布原则 众所周知,所有消息操作都相当脆弱

首先进行显式内容复制,而不是直接操作ZeroMQ传递的指针引用的语法加糖的reinterpret_cast msg.data内容,怎么样

避免在使用zmq_msg_copy复制消息后修改消息内容,这样做可能会导致未定义的行为。如果您需要的是实际的硬拷贝,请使用zmq_msg_init_size分配新消息,并使用memcpy复制消息内容

正如已发布的ZeroMQ API中已发布的公平设计实践强烈建议的那样,还建议在创建安全内容副本之后立即显式关闭请求消息对象

永远不要直接访问zmq_msg_t成员,而是始终使用zmq_msg函数族


ZeroMQ API明确警告不要尝试使用API发布的函数/方法以外的任何其他方式操纵任何消息内容。最好避免任何这样的把戏,即使代价是更长的代码和更多的SLOC-s。

您确定zmq消息消息中有空终止符吗

_msg.ParseFromStringreinterpret_castmsg.data

如果不是的话,当它读到你认为是一个字符串的末尾时,它会用垃圾填充你的消息

我问的原因是:

创建/发送消息时,不包括空值

zmq::message_t request(_msg.ByteSize());
std::string value = _msg.SerializeAsString();
memcpy(request.data(), reinterpret_cast<const void*>(value.c_str()), value.size());
return request;
void set_probed_value(const double& val)
{
    _msg.clear_probed();
    _msg.set_probed(val);
}
zmq::message_t request(_msg.ByteSize());
std::string value = _msg.SerializeAsString();
memcpy(request.data(), reinterpret_cast<const void*>(value.c_str()), value.size());
return request;