17

I am a new-by to ZeroMQ and make my way through the C++ hello-world example of the echo client-server pattern (Request-Reply). The server looks like:

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

Now my question: How can I access / read the real data that socket.recv() ? Trying:

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

resulted in an error message:

 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’

The same goes for the client side that is sending the message. I don't find a way to display the real message...

mpromonet
  • 11,326
  • 43
  • 62
  • 91
dhpizza
  • 361
  • 1
  • 2
  • 10
  • I believe the ZeroMQ documentation has examples in C++. Have you looked at those? – larsks Jun 05 '12 at 16:39
  • 1
    You're right, there is an entry for zmq_msg_data that says "The zmq_msg_data() function shall return a pointer to the message content of the message object referenced by msg." But how do I do this explicitly? – dhpizza Jun 05 '12 at 16:55
  • No, I mean the [Guide](http://zguide.zeromq.org/) is full of C++ code examples. – larsks Jun 05 '12 at 17:31
  • 1
    I read the guide but unfortunately it doesn't include what I'm looking for... – dhpizza Jun 05 '12 at 17:36
  • 4
    @Iarsks have you read the guide ? If you have then you would recognize the above code as being from the guide. In there they just say "received hello" instead of actually reading the message that was sent. I've actually come here for the very same question as the OP. – Void Nov 04 '13 at 17:50

3 Answers3

46

The hello world example goes only half way and outputs the hard-coded values:

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

Printing the actual response can be done as follows:

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

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

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

There are some other useful examples in zhelpers.hpp.

Nikolai Koudelia
  • 2,494
  • 1
  • 26
  • 28
1

I found that the following does what I want:

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;

where msglen is of type int and myMessage is const char * tyoe. In this way, the server receives a human readable message. Hope this is not against any zeromq rules...

dhpizza
  • 361
  • 1
  • 2
  • 10
  • 1
    Since you are in C++ why not use strings ? I mean char* are just a pain unless you really need them for some obscure reasons (other libraries for example). – Void Nov 04 '13 at 17:52
1

While I think we need to go through the guide before we can write elegant ZeroMQ codes. I found lines of simple codes from the HELLO WORLD example for extracting data received from the socket and sending back response:

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

However, this solution does not specify the length of received data, following Nikolai Koudelia's way above, I make a string for received data:

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