为什么zmq REQ-REP无法正常工作?

时间:2017-06-19 12:34:24

标签: c++ network-programming zeromq distributed-computing

我有1个主人(使用 REQ )和2个奴隶(A,B)使用 REP 。主设备向其中一个从设备发送请求并期待他的响应。

即使我在ZMQ信封中设置了地址,也会将消息发送到错误的从站。如何指定从站地址?我认为我在master中正确设置它,但它不能正常工作并以循环方式从主服务器发送请求。

master.cpp

#include "zhelpers.hpp"
#include <string>

int main (int argc, char *argv[])
{
    zmq::context_t context(1);
    zmq::socket_t requester(context, ZMQ_REQ);
    requester.setsockopt(ZMQ_IDENTITY,"M");
    requester.bind("tcp://*:5559");

    for( int request = 0 ; request < 10 ; request++) {

        std::string cmd;
        std::cin>>cmd;
        s_sendmore (requester, "B");
        s_sendmore (requester, "");
        s_send (requester, cmd);
        s_dump(requester);
    }
}

slaveA.cpp

#include "zhelpers.hpp"

int main (int argc, char *argv[])
{
    zmq::context_t context(1);
    zmq::socket_t responder(context, ZMQ_REQ);
    responder.setsockopt(ZMQ_IDENTITY, "A", 1);
    responder.connect("tcp://localhost:5559");
    while(1)
    {
        s_dump(responder);
        sleep (1);//
//        s_sendmore (responder, "M"); //Should I set this ??
//        s_sendmore (responder, "");
        s_send (responder, "FromSlaveA");
    }
}

slaveB.cpp

#include "zhelpers.hpp"

int main (int argc, char *argv[])
{
    zmq::context_t context(1);
    zmq::socket_t responder(context, ZMQ_REP);
    responder.setsockopt(ZMQ_IDENTITY, "B", 1);
    responder.connect("tcp://localhost:5559");

    while(1)
    {
        s_dump(responder);
        sleep (1);
        s_send (responder, "FromSlaveB");
    }
}

有什么问题? 操作系统:Ubuntu 16.04,ZMQ版本4.X.X

更新1:

将slaveA套接字更改为REP但仍然是master以循环方式将消息发送到slaveA和SlaveB。现在,我想我是否正确地将消息信封设置为slaveB?但是当我打印信封时,我在奴隶那里得到了这个,证明我正确地将信封设置为B,不是吗?

[001]B
[000]
[005]jjjjj

1 个答案:

答案 0 :(得分:0)

你的 slaveA.cpp 应该使用正确的ZeroMQ接入点原型:

zmq::socket_t responder( context, ZMQ_REP );    // !ZMQ_REQ);

Post Festum:在生成问题之前要阅读两次的文档

  

ZMQ_IDENTITY :设置套接字标识
  
  ZMQ_IDENTITY选项在连接到ROUTER套接字时应设置指定套接字的标识。标识长度应为1到255个字节,并且可以包含任何值。

  如果两个客户端在连接到ROUTER时使用相同的标识,则结果将取决于ZMQ_ROUTER_HANDOVER选项设置。如果未设置(或设置为默认值为零),ROUTER套接字将拒绝尝试连接已使用标识的客户端。如果该选项设置为1,则ROUTER套接字应切换到新客户端的连接并断开现有客户端的连接。

       Option value type binary data
       Option value unit N/A
       Default value NULL
       Applicable socket types ZMQ_REQ, ZMQ_REP, ZMQ_ROUTER, ZMQ_DEALER.

抱歉,这种 .setsockopt() 设置为:
1)此功能具有出色的记录具有操作的所有相关细节&amp;可能的使用概念
2)仅对于代码中不存在的对象有意义 3)决定与您的代码无关的功能行为 4)对于传出流量,此功能与代码中存在的对象的硬连线循环传递完全无关

因此,阅读文档,它“足够”并且是一种专业的方法来避免产生问题。

Q.E.D。