【问题标题】:Zeromq: How to access tcp message in c++Zeromq:如何在 C++ 中访问 tcp 消息
【发布时间】:2012-06-09 16:52:12
【问题描述】:

我是 ZeroMQ 的新手,并通过 C++ hello-world 示例回显客户端-服务器模式 (Request-Reply)。服务器看起来像:

//
// 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’

发送消息的客户端也是如此。我找不到显示真实信息的方法...

【问题讨论】:

  • 我相信 ZeroMQ 文档中有 C++ 示例。你看过那些吗?
  • 你说得对,zmq_msg_data 有一个条目,上面写着“zmq_msg_data() 函数应返回指向 msg 引用的消息对象的消息内容的指针。”但是我该如何明确地做到这一点?
  • 不,我的意思是Guide 充满了 C++ 代码示例。
  • 我阅读了该指南,但不幸的是它不包括我正在寻找的内容......
  • @Iarsks 你读过指南吗?如果你有,那么你会认出上面的代码来自指南。在那里他们只是说“收到你好”而不是实际阅读发送的消息。实际上,我来这里是为了与 OP 相同的问题。

标签: c++ tcp zeromq


【解决方案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);

但是,这个解决方案没有指定接收数据的长度,按照上面Nikolai Koudelia的方式,我为接收到的数据制作了一个字符串:

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

【讨论】:

    【解决方案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 规则...

    【讨论】:

    • 既然您在 C++ 中,为什么不使用字符串?我的意思是 char* 只是一种痛苦,除非你真的因为一些晦涩的原因需要它们(例如其他库)。
    【解决方案3】:

    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 中还有一些其他有用的示例。

    【讨论】:

    • 很好的第一个答案@NikolaiKoudelia。
    • 你是使用zmq的c绑定(cppzmq)还是zmq没有任何绑定?
    • 是的,需要绑定(zmq.hpp)。
    • 很棒的反应。这确实应该包含在 Hello World 示例中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-20
    • 2014-11-07
    • 2019-11-08
    • 1970-01-01
    相关资源
    最近更新 更多