2012-06-05 8 views
11

Jestem nowicjuszem w ZeroMQ i robię sobie drogę przez przykład hello-world C++ dla wzorca klienta-serwera echa (Request-Reply). Serwer wygląda następująco:Zeromq: Jak uzyskać dostęp do wiadomości tcp w języku 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; 
} 

Teraz moje pytanie: W jaki sposób można uzyskać dostęp do/czytać prawdziwe dane, które socket.recv()? Próbując:

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

powodowało wyświetlenie komunikatu o błędzie:

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’ 

To samo po stronie klienta, który wysyła wiadomość. Nie znaleźć sposób, aby wyświetlić wiadomość prawdziwe ...

+0

Wierzę, że dokumentacja ZeroMQ ma przykłady w C++. Czy na nie spojrzałeś? – larsks

+1

Masz rację, jest wpis dla zmq_msg_data, który mówi "Funkcja zmq_msg_data() zwróci wskaźnik do treści wiadomości obiektu wiadomości przywoływanego przez msg." Ale w jaki sposób zrobić to wyraźnie? – dhpizza

+0

Nie, mam na myśli [Guide] (http://zguide.zeromq.org/) jest pełen przykładów kodu C++. – larsks

Odpowiedz

33

Przykład hello world idzie tylko pół drogi i wyprowadza na stałe wartości:

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

Drukowanie rzeczywistą odpowiedź może być wykonane jako to:

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

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

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

Istnieje kilka innych przydatnych przykładów w zhelpers.hpp.

+0

Dobra pierwsza odpowiedź @NikolaiKoudelia. – thomasfedb

+0

Czy używasz c wiązania zmq (cppzmq) lub zmq bez wiązania? –

+0

Tak, wiązanie (zmq.hpp) jest potrzebne. –

2

okazało się, że po robi to, co chcę:

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; 

gdzie msglen jest typu int i myMessage jest const char * tyoe. W ten sposób serwer otrzymuje wiadomość czytelną dla człowieka. Mam nadzieję, że nie jest to sprzeczne z żadnymi regułami zerowymi ...

+1

Skoro jesteś w C++, czemu nie używać ciągów? Chodzi mi o to, że char * to tylko ból, chyba że naprawdę potrzebujesz ich z pewnych niejasnych powodów (na przykład inne biblioteki). – Void

1

Chociaż myślę, że musimy przejść przez przewodnik, zanim będziemy mogli pisać eleganckie kody ZeroMQ. Znalazłem linii prostych kodów z Hello World przykład do ekstrakcji danych otrzymanych od gniazda i odesłaniem odpowiedzi:

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

Jednak to rozwiązanie nie określa długość odebranych danych, po Nikolai Koudelia powyżej, tworzę ciąg znaków dla otrzymanych danych:

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