I need to send a leap motion frame via network using ZeroMQ.
The send and receive functionality already seems to work but I have a problem with the data being sent.
The Leap::Frame class contains a serialize and a deserialze method which creates a byte string of the given frame (or recreates a frame from a string).
For this simple example I send the string without beeing encapsulated in any class or something else from the client to the server.
The problem is that the byte string seems to have some \0 in it and so only the data till the first \0 arrives at the server.
The client:
int main(int argc, char** argv)
{
Leap::Controller controller;
zmq::context_t context = zmq::context_t(1);
zmq::socket_t client = zmq::socket_t(context, ZMQ_REQ);
client.connect("tcp://192.168.0.101:6881");
while(true)
{
Leap::Frame frame = controller.frame(0);
std::string frame_string = frame.serialize();
zmq::message_t message( frame_string.size() );
memcpy(message.data(), &frame_string, frame_string.size());
client.send(message);
}
return 0;
}
The server:
int main(int argc, char** argv)
{
zmq::context_t context = zmq::context_t(1);
zmq::socket_t server = zmq::socket_t(context, ZMQ_REP);
server.bind("tcp://*:6881");
while(true)
{
zmq::message_t message;
server.recv(&message);
std::string frame_string(static_cast<char*>(message.data()), message.size());
Leap::Frame received_frame;
received_frame.deserialize(frame_string);
}
return 0;
}
These are the first 200 chars of a serialized frame on the client side (total size for a frame with one hand is around 3700 chars). The first of many \0's is at position 149 (highlighted in bold):
s\x1è\x1d\bÒϤ\x2\x10ÝË裧\x1\x1až\x3\b2\"3\n\xf\rEÝ{Á\x15Ì\x1d“C \x1dæx•Á\x12\xf\r²\b\r¾\x15w/õ=\x1d†³{¿\x1a\xf\rw+ŠB\x15Ò0¡A\x1dB- \x6B*\xf\rôX\x1a?\x15è\x5G¿\x1d|k7¾2!\n\xf\rœ„ÚÂ\x15¯£ÍC\x1d6´G \x15\x1fÁ\x18C\x18ÿÿÿÿÿÿÿÿÿ\x1:\x1b\tzù\x1c”hª\x1eÀ\x11jÆaê‘HIÀ \x19\t‡\0p0_@ÀBW\n\x1b\t8O\x13U\x15Õï?\x11Y\x2\a;Y=²¿\x19fó™Æ<IJ? \x12\x1b\t\x12\x1>\b<±?\x117T\x2
On the server side the following arrives:
s\x1è\x1d\bÒϤ\x2\x10ÝË裧\x1\x1až\x3\b2\"3\n\xf\rEÝ{Á\x15Ì\x1d“C \x1dæx•Á\x12\xf\r²\b\r¾\x15w/õ=\x1d†³{¿\x1a\xf\rw+ŠB\x15Ò0¡A\x1dB- \x6B*\xf\rôX\x1a?\x15è\x5G¿\x1d|k7¾2!\n\xf\rœ„ÚÂ\x15¯£ÍC\x1d6´G \x15\x1fÁ\x18C\x18ÿÿÿÿÿÿÿÿÿ\x1:\x1b\tzù\x1c”hª\x1eÀ\x11jÆaê‘HIÀ \x19\t‡
So unsurprisingly only the chars until the first \0 arrive at the server.
Does anybody know a workaround to send a byte array with \0's in it or another way to solve this problem?
The solution should be as fast as possible since the leap sensor creates about 100 frames or more (up to 200) per second and I need to get as many of them as possible.
Thanks in advance.
Try initializing the message you send with the size. Currently your memcpy'ing into msg.data() but it's not been allocated.
zmq::message_t message( frame_string.size() );
memcpy(message.data(), frame_string.c_str(), frame_string.size());
client.send(message);
Also, when receiving a message you don't need to have initialized it with a size, the recv call will resize it for you.
zmq::message_t message;
server.recv(&message);