2014-10-01 3 views
0

У меня плохое понимание того, как правильно работать с 0MZ. Когда я пытаюсь отправить сообщение, инициализированное размером более 29, что-то пойдет не так. Мой код очень прост:ZeroMQ - отправка более 30 байтов с гнездом REQ

zmq::context_t context (1); 
zmq::socket_t req(context,ZMQ_REQ); 
req.connect("tcp://localhost:6969"); 

int msgSize = 100; 
zmq::message_t test(msgSize); 
snprintf((char*)test.data(),msgSize,"short message"); 
cout << static_cast<char*>(test.data())<< endl; // this is always fine - 'short message' 

до сих пор так хорошо, но после отправки этого сообщения, если msgSize> 29, я не могу получить тот же результат снова

req.send(test); 
cout << static_cast<char*>(test.data())<< endl; // now it's gibberish, like '&?+#' 

что еще более загадочные, если мой сервер получает сообщение также выглядит как «? & + #» там, но если он посылает его обратно просто с PUB гнездом, я могу читать его снова в моем клиенте:

zmq::message_t reply; 
req.recv(&reply); 
cout << static_cast<char*>(test.data())<< endl; - 'my message' again! 

I понятие также tand, что для коротких сообщений существует ограничение на 29 байтов, но как я могу обойти его, не имея дело с многостраничными сообщениями? Я буквально нуждаюсь в 40 символах ....

+1

В соответствии с документацией 0MQ для [zmq_send()] (http://api.zeromq.org/2-1:zmq-send), успешным вызовом этой функции ('zmq :: socket_t :: send' wraps он) уничтожает сообщение. Таким образом, вы не должны обращаться к члену данных ** после того, как ** сообщение было поставлено в очередь. То, что он работает для небольших сообщений, вероятно, является артефактом реализации. –

+0

Но почему мое сообщение испортилось и на сервере? –

+0

Обратите внимание, что в последних трех строках кода полученное сообщение называется 'reply', но вы все равно печатаете содержимое данных' test'. –

ответ

1

Если сообщение составляет> 30 байт, память, занятая «тестом», а затем освобожденная, должна повторно использоваться данными ответа (очевидно, с помощью serendipity). Таким образом, когда вы снова смотрите на «тест», это, похоже, выглядит так, как вы думаете. Эта теория должна быть очень простой для вас, чтобы проверить в отладчике, просмотрев адреса.

Независимо от того, как сказал Христо, отправка сообщения освобождает его оригинальное содержимое и не должна использоваться снова.

У ZeroMQ есть оптимизация для небольших сообщений, где полезная нагрузка не требуется отдельно выделять. Опять же, факт, что вы все еще можете видеть содержимое, которое вы ожидаете после отправки сообщения, - это просто артефакт; вы не можете полагаться на это.

Если у вас есть требование сохранить содержимое сообщений после их отправки, ознакомьтесь с zmq_send_const(), который является новым с ZMQ 4.0. Я не знаю, используют ли какие-либо привязки.

+0

Я не уверен, но это не объясняет, почему сообщение также неверно на стороне сервера? –

+0

@ClockworkOrkwork Сложно сказать, что вы не разместили свой код сервера. –

+0

Вы правы, сейчас я могу сказать, что есть zmq :: poll, ожидающий сообщений, я добавлю код позже litle –

0

Как оказалось, у меня была ошибка, генерирующий фрагмент кода внутри моего приложения сервера, после получения сообщения я сделал мгновенный пинг-понг стиль ответа, как:

zmq::message_t msg(msgSize); 
REC.recv(&msg); 
//pong 
REC.send(msg); 

И как выше ответ указывает, отправка сообщения освобождает его оригинальное содержимое, оставляя меня с нежелательной бабкой случайных байтов.

Смежные вопросы