cppzmq
cppzmq copied to clipboard
message_t::to_string inserts a trailing null char and breaks string comparisons
Text messages sent via zmq get a trailing null char on the receiver side. The method message_t::to_string[_view] return a string size which is one byte larger than expected. Comparison between such returned strings are broken unless one manually constructs a longer string and then sets the last char to null.
// req.cpp
#include <string>
#include <iostream>
#include <zmq.hpp>
int main() {
zmq::context_t ctx;
zmq::socket_t sock(ctx, zmq::socket_type::req);
sock.connect("ipc:///tmp/zmqsocket");
zmq::message_t msg{"abc"};
sock.send(msg);
sock.recv(msg);
std::cout << msg.to_string_view() << std::endl;
return 0;
}
// rep.cpp
#include <string>
#include <iostream>
#include <zmq.hpp>
int main() {
zmq::context_t ctx;
zmq::socket_t sock(ctx, zmq::socket_type::rep);
sock.bind("ipc:///tmp/zmqsocket");
zmq::message_t msg;
while (true) {
std::cout << "listening..." << std::endl;
sock.recv(msg);
// msg.to_string_view() returns "abc\0", therefore msg.to_string_view() != "abc"
// note that the trailing null char eludes printing functions
// When constructing strings C++ optimizes away trailing null chars
// One needs to build a longer string and set the last char to null later
std::string s{"abcX"};
s[3] = '\0';
// now the comparison works
if ( msg.to_string_view() == s) {
sock.send(zmq::buffer("def"));
} else {
sock.send(zmq::buffer("???"));
}
}
return 0;
}