2012-06-05 19 views
11

Soy un recién llegado a ZeroMQ y hago mi camino a través del ejemplo del hello-world de C++ del patrón echo cliente-servidor (Solicitud-Respuesta). El servidor parece:Zeromq: Cómo acceder al mensaje tcp en C++

// 
// 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; 
} 

Ahora mi pregunta: ¿Cómo puedo acceder/leer los datos reales que socket.recv()? Tratando:

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

dio como resultado un mensaje de error:

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’ 

Lo mismo vale para el lado del cliente que envía el mensaje. No encuentro una forma de mostrar el mensaje real ...

+0

Creo que la documentación de ZeroMQ tiene ejemplos en C++. ¿Has mirado eso? – larsks

+1

Tiene razón, hay una entrada para zmq_msg_data que dice "La función zmq_msg_data() devolverá un puntero al contenido del mensaje del objeto de mensaje al que hace referencia msg". ¿Pero cómo hago esto explícitamente? – dhpizza

+0

No, me refiero a que [la Guía] (http://zguide.zeromq.org/) está llena de ejemplos de código C++. – larsks

Respuesta

33

El ejemplo hola mundo va sólo a mitad de camino y da salida a los valores no modificables:

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

la impresión de la respuesta real se puede realizar como sigue:

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

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

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

Hay otros ejemplos útiles en zhelpers.hpp.

+0

Nice first answer @NikolaiKoudelia. – thomasfedb

+0

¿está utilizando el enlace c de zmq (cppzmq) o zmq sin ningún enlace? –

+0

Sí, se necesita el enlace (zmq.hpp). –

2

encontré que el siguiente no lo que yo quiero:

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; 

donde msglen es de tipo int y myMessage es const char * tyoe. De esta forma, el servidor recibe un mensaje legible por humanos. Espero que esto no vaya en contra de ninguna regla de zeromq ...

+1

Como estás en C++, ¿por qué no usar cadenas? Quiero decir char * son solo un dolor a menos que realmente los necesites por algunas razones oscuras (otras bibliotecas, por ejemplo). – Void

1

Aunque creo que tenemos que pasar por la guía antes de poder escribir códigos ZeroMQ elegantes. He encontrado líneas de códigos simples de la ejemplo HOLA MUNDO para la extracción de los datos recibidos de la toma y el envío de vuelta respuesta:

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); 

Sin embargo, esta solución no especifica la longitud de los datos recibidos, tras Nikolai Koudelia De la manera anterior, hago una cadena para los datos recibidos:

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