【问题标题】:Binding a subscriber socket and connecting a publisher socket in ZeroMQ is giving error when the code is run. Why?运行代码时,在 ZeroMQ 中绑定订阅者套接字并连接发布者套接字会出错。为什么?
【发布时间】:2018-03-07 14:52:29
【问题描述】:

在此代码中,订阅者(在subscriber.cpp 代码中)套接字绑定到端口 5556。

它从发布者(subscriber.cpp)接收更新/消息,发布者套接字在 5556 处连接到订阅者并向其发送更新/消息。

我知道约定是给.bind() 发布者,而不是在上面调用.connect()。但理论上每个套接字类型都可以.bind().connect()

但是,这两个代码在运行时都会出现 zmq 错误。 为什么?

这是 CPP 代码。

publisher.cpp

#include <iostream>
#include <zmq.hpp>
#include <zhelpers.hpp>

using namespace std;
int main () {

zmq::context_t context (1);
zmq::socket_t publisher(context, ZMQ_PUB);
publisher.connect("tcp://*:5556");
while (1) {

    zmq::message_t request (12);
    memcpy (request.data (), "Pub-1 Data", 12);
    sleep(1);
    publisher.send (request);
}
return 0;
}

subcriber.cpp

#include <iostream>
#include <zmq.hpp>

int main (int argc, char *argv[])
{
zmq::context_t context (1);
zmq::socket_t subscriber (context, ZMQ_SUB);
subscriber.bind("tcp://localhost:5556");
subscriber.setsockopt(ZMQ_SUBSCRIBE, "", 0); // subscribe to all messages

//  Process 10 updates
int update_nbr;
for (update_nbr = 0; update_nbr < 10 ; update_nbr++) {

    zmq::message_t update;
    subscriber.recv (&update);
    std::string updt = std::string(static_cast<char*>(update.data()), update.size());
    std::cout << "Received Update/Messages/TaskList " << update_nbr <<" : "<< updt << std::endl;
}
return 0;
}

【问题讨论】:

  • theory every socket type can bind or connect no - udp 不建立连接。您绑定到两侧的端口并将数据发送到另一端......没有任何东西可以确保接收到数据;或者会告诉你它是
  • 好的。但是请告诉为什么上面的代码失败了。@UKMonkey
  • 我必须安装 zeromq;拿走你的代码;然后按照ericlippert.com/2014/03/05/how-to-debug-small-programs 中的步骤进行操作,如果您说出错误是什么会有所帮助;但是在尝试执行这样复杂的任务之前,学习调试自己的程序是必不可少的
  • 能否请您也发布 ZeroMQ 版本 + zmq_error 编号 + 它实际发生的位置? (所有正常的调试细节)
  • 版本:4.2.3 运行程序后,这是我得到的输出:for publisher.cpp "terminate 在抛出'zmq::error_t'的实例后调用什么():无效参数中止“对于subscriber.cpp:”在抛出'zmq :: error_t'实例后调用终止what():没有这样的设备中止”

标签: c++ zeromq publish-subscribe


【解决方案1】:

不,逆向.bind()/.connect()没有问题

这基本上可以正常工作。

然而,PUB/SUB正式原型是subject to a so called late-joiner syndrome.

如果没有彻底的调试细节,正如上面所要求的,人们可能只是重复一般的经验法则:

在较新的 API 版本中,可能
添加rc = &lt;aSocket&gt;.setsockopt( ZMQ_CONFLATE, 1 ); assert( rc &amp; "CONFLATE" );
添加rc = &lt;aSocket&gt;.setsockopt( ZMQ_IMMEDIATE, 1 ); assert( rc &amp; "IMMEDIATE" );
等等,
所有这些都是为了更好地调整 context-instance + socket-instance 属性,从而最大限度地减少后期加入综合症的影响。

【讨论】:

  • 更新:当我更改行时代码正在工作 -subscriber.bind("tcp://localhost:5556");到subscriber.bind("tcp://*:5556");和 publisher.connect("tcp://*:5556");到 publisher.connect("tcp://localhost:5556");
  • 对,错误痕迹可能看起来很神秘,但很清楚 - 第一个与符号名称翻译有关,第二个是从 .bind() 方法手动更改/编辑的 SLOC 的残余废话,对 .connect() 有意义的地方,通配符扩展失去了意义。 很高兴您已经调试到根本原因。
【解决方案2】:

反向bind()/connect()没有问题。 当我更改行时,代码正在工作 -subscriber.bind("tcp://localhost:5556"); 到 订阅者.bind("tcp://:5556"); 和 publisher.connect("tcp://:5556"); 到 publisher.connect("tcp://localhost:5556");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多