Cppzmq - 路由器到路由器的通信在初始连接时卡住

问题描述 投票:0回答:1

我正在尝试使用 cppzmq 从 PyZMQ 重新创建路由器到路由器示例。我测试了 Python 版本,行为符合预期(即客户端连接到服务器,服务器发送回复)。

但是,我的 C++ 版本在初始连接时卡住了(或者如果设置了

router_mandatory
,则抛出主机无法访问错误)。 将客户端套接字类型更改为经销商会导致预期的消息流。

我怀疑我以某种方式弄乱了身份/路由,但我太卡住了,看不到我哪里出了问题。

服务器.cpp

#include <zmq.hpp>
#include <zmq_addon.hpp>
#include <iostream>
#include <vector>
#include <string>

int main() {
    zmq::context_t context(1);
    zmq::socket_t server(context, zmq::socket_type::router);
    server.set(zmq::sockopt::routing_id, "server");
    server.bind("tcp://*:4000");

    while (true) {
        std::cout << "Waiting for msg" << std::endl; 

        std::vector<zmq::message_t> recv_msgs;
        zmq::recv_multipart(server, std::back_inserter(recv_msgs));

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

        server.send(recv_msgs[0], zmq::send_flags::sndmore);
        server.send(zmq::message_t(), zmq::send_flags::sndmore);
        server.send(zmq::buffer("Response from server"), zmq::send_flags::none);
    }

    return 0;
}

客户端.cpp

#include <zmq.hpp>
#include <zmq_addon.hpp>
#include <array>
#include <iostream>
#include <string>

int main() {
    zmq::context_t context(1);
    zmq::socket_t client(context, zmq::socket_type::router);
    client.set(zmq::sockopt::routing_id, "client");
    client.connect("tcp://127.0.0.1:4000");

    // Send a request to the server
    std::array<zmq::const_buffer, 3> bufs = {
      zmq::buffer("server"), // set identity of server we try to reach
      zmq::str_buffer(""),
      zmq::str_buffer("Hello, Server!")
    };
    zmq::send_multipart(client, bufs);

    // Receive the response
    zmq::message_t reply;
    zmq::message_t identity;
    client.recv(identity, zmq::recv_flags::none);
    client.recv(reply, zmq::recv_flags::none);

    std::string reply_message(static_cast<char*>(reply.data()), reply.size());
    std::cout << "Received reply: " << reply_message << std::endl;

    return 0;
}
  • 我阅读了指南
  • 我在 github 上检查了类似的 问题
  • 我尝试了身份、缓冲区、多部分消息和套接字类型的几种变体(作为健全性检查)
c++ zeromq
1个回答
0
投票

根据以下补丁修改您的

client.cpp

--- client1.cc  2024-08-18 21:07:00.000000000 +0000
+++ client2.cc  2024-08-18 21:08:00.000000000 +0000
@@ -1,18 +1,21 @@
 #include <zmq.hpp>
 #include <zmq_addon.hpp>
 #include <array>
+#include <chrono>
 #include <iostream>
 #include <string>
+#include <thread>
 
 int main() {
     zmq::context_t context(1);
     zmq::socket_t client(context, zmq::socket_type::router);
     client.set(zmq::sockopt::routing_id, "client");
     client.connect("tcp://127.0.0.1:4000");
+    std::this_thread::sleep_for(std::chrono::milliseconds{100});
 
     // Send a request to the server
     std::array<zmq::const_buffer, 3> bufs = {
-      zmq::buffer("server"), // set identity of server we try to reach
+      zmq::str_buffer("server"), // set identity of server we try to reach
       zmq::str_buffer(""),
       zmq::str_buffer("Hello, Server!")
     };

有两个变化:

  • 我在连接后添加了一点延迟。这是必要的,因为 ZeroMQ 异步工作并且在后台线程中工作。因此,当
    client.connect(...)
    返回时,不保证连接能够建立。短暂的延迟可确保建立连接并传递消息。
  • 我将多部分消息的第一部分更改为
    str_buffer

关于连接: 依赖延迟是一种活泼的行为,但并不理想。更好的解决方案可能是通过 zmq_socket_monitor (或等效的 cppzmq)监视连接状态并等待

ZMQ_EVENT_CONNECTED
。我希望在连接完全建立(交换路由 ID)后传递此事件,但我不确定。值得一试。

© www.soinside.com 2019 - 2024. All rights reserved.