2014-10-01 153 views
0

我很難理解如何正確使用0MZ。當我試圖發送大於29的初始化消息時,出現了問題。我的代碼是非常簡單的:ZeroMQ - 使用REQ套接字發送超過30個字節

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! 

我unders tand,短消息有29個字節的限制,但是我怎樣才能解決它,而不處理多部分消息?我真的需要像40個字符....

+1

根據[zmq_send()](http://api.zeromq.org/2-1:zmq-send)的0MQ文檔,成功調用該函數('zmq :: socket_t :: send')它)破壞消息。所以在消息排隊後,你不應該訪問數據成員**。它適用於較小的消息可能是一個實現人工製品。 – 2014-10-01 07:11:59

+0

但是爲什麼我的信息也在服務器上搞砸了? – 2014-10-01 07:16:59

+0

請注意,在顯示的最後3行代碼中,接收到的消息被稱爲「reply」,但您仍然會打印「test」的數據內容。 – 2014-10-01 10:55:10

回答

1

如果消息是> 30個字節,內存曾經被'測試'佔用,但隨後被釋放,必須被回覆數據(顯然是偶然)重用。因此,當你再次看「測試」時,它神奇地似乎是你認爲應該是的。這個理論應該非常簡單,通過查看地址來驗證調試器。

無論如何,正如Hristo所說,發送消息可以釋放它的原始內容,不應再次使用。

ZeroMQ針對小型消息進行了優化,其中有效載荷不需要單獨分配。同樣,在發送消息之後,您仍然可以看到您期望的內容的事實只是一種人造物;你不能依靠它。

如果您有要求在發送郵件後保留郵件的內容,請查看zmq_send_const(),這是ZMQ 4.0的新增功能。我不知道是否有任何綁定使用它。即時乒乓式的答覆,像

+0

我不確定,但是這並不解釋爲什麼在服務器端的消息也錯了? – 2014-10-01 09:21:57

+0

@ClockworkOrkwork很難說,你還沒有發佈你的服務器代碼。 – 2014-10-01 11:12:17

+0

你是對的,現在我可以說有一個zmq :: poll等待消息,我會稍後添加代碼 – 2014-10-01 11:18:08

0

事實證明,我有一個錯誤產生一張我的服務器應用程序中的代碼,接收消息我做後:

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

正如上面的回答指出,發送一條消息可以釋放它的原始內容,使我不必要的亂碼隨機字節。

相關問題