2012-06-05 22 views
11

我是ZeroMQ的新手,並通過回聲客戶端 - 服務器模式(請求 - 回覆)的C++ hello-world示例進行創作。服務器看起來像:Zeromq:如何訪問C++中的tcp消息

// 
// Hello World server in C++ 
// Binds REP socket to tcp://*:5555 
// Expects "Hello" from client, replies with "World" 
// 
#include <zmq.hpp> 
#include <string> 
#include <iostream> 
#include <unistd.h> 

int main() { 
    // Prepare our context and socket 
    zmq::context_t context (1); 
    zmq::socket_t socket (context, ZMQ_REP); 
    socket.bind ("tcp://*:5555"); 

    while (true) { 
     zmq::message_t request; 

     // Wait for next request from client 
     socket.recv (&request); 
     std::cout << "Received Hello" << std::endl; 

     // Do some 'work' 
     sleep (1); 

     // Send reply back to client 
     zmq::message_t reply (5); 
     memcpy ((void *) reply.data(), "World", 5); 
     socket.send (reply); 
    } 
    return 0; 
} 

現在我的問題:我如何訪問/讀取socket.recv()的真實數據?嘗試:

std::cout << request << std::endl; 

導致的錯誤消息:

error: no match for ‘operator<<’ in ‘std::operator<< [with _Traits = 
std::char_traits<char>](((std::basic_ostream<char, std::char_traits<char> >&) 
(& std::cout)), ((const char*)"Received Hello")) << request’ 

這同樣適用於被髮送消息的客戶端。我沒有找到一個方法來顯示真正的消息...

+0

我相信ZeroMQ文檔在C++中有例子。你看過那些嗎? – larsks

+1

你說的沒錯,有一個zmq_msg_data條目說:「zmq_msg_data()函數將返回一個指向由msg引用的消息對象的消息內容的指針。」但是,我如何明確地做到這一點? – dhpizza

+0

不,我的意思是[指南](http://zguide.zeromq.org/)是完整的C++代碼示例。 – larsks

回答

33

hello world示例只有去一半,輸出硬編碼值:

std::cout << "Received Hello" << std::endl; 

打印的實際響應是可以做到如下:

zmq::message_t reply; 
socket.recv (&reply); 

std::string rpl = std::string(static_cast<char*>(reply.data()), reply.size()); 

std::cout << rpl << std::endl; 

zhelpers.hpp還有一些其他有用的例子。

+0

尼斯萊第一次回答@尼古拉·孔迪莉亞。 – thomasfedb

+0

你使用zmq(cppzmq)的c綁定還是zmq沒有任何綁定? –

+0

是的,綁定(zmq.hpp)是必需的。 –

2

我發現下面我想要做什麼:

zmq::message_t request (msglen); 
memcpy ((void *) request.data(), myMessage, msglen); 
char * requestmsg = new char [msglen]; 
memcpy (requestmsg, request.data(), request.size()); 
requestsocket.send (request); 
std::cout << "Sending " << requestmsg << std::endl; 

其中msglen是int類型和myMessage是爲const char * tyoe。 這樣,服務器就會收到一條人類可讀的消息。 希望這不是針對任何zeromq規則...

+1

既然你是在C++爲什麼不使用字符串?我的意思是char *只是一個痛苦,除非你真的需要一些不起眼的原因(例如其他庫)。 – Void

1

雖然我認爲在編寫優雅的ZeroMQ代碼之前我們需要經過指南。我發現從HELLO WORLD示例的簡單代碼線,用於提取從所述插座接收到的數據和發送迴響應:

zmq::message_t request; 
    socket.recv (&request); 
    std::cout << "Received request: [" << (char*) request.data() << "]" << std::endl; 
    // Do some 'work' 
    Sleep (1); 
    // Send reply back to client 
    zmq::message_t reply (6); 
    memcpy ((void *) reply.data(), "World", 6); 
    socket.send (reply); 

然而,這種解決方案並沒有指定接收的數據的長度,以下尼古拉Koudelia上面的方式,我爲接收到的數據創建一個字符串:

std::cout << "Received request: [" << std::string(static_cast<char*>(request.data()), request.size()) << "]" << std::endl;