我正在尝试在我的简单发布商订阅者计划中使用epgm
传输,但我无法这样做。根据我的理解,我无法在bind
和connect
语句中提供正确的地址字符串。
发布者和订阅者可以在相同或不同的计算机上运行。
以下是使用tcp
传输并正常工作的必需代码。它使用cppzmq
:https://github.com/zeromq/cppzmq。
发布商代码:
#include <zmq.hpp>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
int main () {
zmq::context_t context (1);
zmq::socket_t publisher (context, ZMQ_PUB);
publisher.bind("tcp://10.1.1.8:5000");
int i = 0;
while (1) {
int topic = 101;
zmq::message_t message(50);
snprintf ((char *) message.data(), 50, "%03d %10d %10d", topic, i, i);
//fprintf(stderr, "message: %s\n", (char *) message.data());
publisher.send(message);
++i;
}
return 0;
}
订阅者代码:
#include <zmq.hpp>
#include <iostream>
#include <sstream>
#include <unistd.h>
#include <cassert>
int main (int argc, char *argv[]) {
zmq::context_t context (1);
zmq::socket_t subscriber (context, ZMQ_SUB);
subscriber.connect("tcp://10.1.1.8:5000");
const char *filter = "101 ";
subscriber.setsockopt(ZMQ_SUBSCRIBE, filter, strlen (filter));
zmq::message_t tp;
int maxx = 0;
for (int i = 0; i < 1000; ++i) {
zmq::message_t update;
int topic, a, b;
if(subscriber.krecv(&update, ZMQ_DONTWAIT)) {
//fprintf(stderr, "size of data received: %zd\n", sizeof(update.data()));
std::istringstream iss(static_cast<char*>(update.data()));
iss >> topic >> a >> b;
assert(a == b);
}
else {
--i;
}
maxx = a > maxx ? a : maxx;
}
fprintf(stderr, "maxx = %d\n", maxx);
return 0;
}
订阅者使用的 krecv
方法:
inline bool krecv (message_t *msg_, int flags_ = 0) {
int nbytes = zmq_msg_recv (&(msg_->msg), ptr, flags_);
if (nbytes >= 0)
return true;
if (zmq_errno () == EAGAIN)
return false;
return false;
}
我尝试将发布商中的bind
语句更改为以下内容:
publisher.bind("epgm://10.1.1.8:5000");
publisher.bind("epgm://224.1.1.1:5000");
publisher.bind("epgm://eth0;224.1.1.1:5000");
publisher.bind("epgm://10.1.1.8;224.1.1.1:5000");
publisher.bind("epgm://localhost:5000");
对于所有5个案例,该程序与Assertion failed: false (src/pgm_socket.cpp:165)
崩溃。对于第五种情况(epgm://localhost:5000
),我还会收到以下警告以及崩溃:
Warn: Interface lo reports as a loopback device.
Warn: Interface lo reports as a non-multicast capable device.
如何解决此问题?我猜测发布者和订阅者的地址变化都是一样的吗?
我将libpgm 5.2.122
与zeromq-4.1.3
一起使用。
请注意,本机具有以下界面:
eth0
(以太网) - inet addr:10.1.1.8
ib0
(InfiniBand) - inet addr:10.1.3.8
lo
(本地环回) - inet addr:127.0.0.1
答案 0 :(得分:0)
尝试在绑定中使用239.0.0.0/8
IP:
publisher.bind("epgm://;239.0.0.1:5000");
RFC 2365将239.0.0.0/8范围分配给组织内的私人使用。根据RFC,发往管理范围内的IPv4多播地址的数据包不会越过管理范围内定义的组织边界,并且管理范围内的IPv4多播地址是本地分配的,不必具有全局唯一性。
答案 1 :(得分:0)
我在Linux上将epgm
与zeromq
一起使用,正确配置很棘手
假设您使用的是Linux,请阅读以下内容,如果没有,我对Windows没有任何经验,所以请忽略:
epgm
不适用于Linux上的回送适配器,因此请忘记这一点。eth0
应该可以工作。是否确实启用了MCAST
(选中ifconfg
)?我将zeromq
与openpgm
链接在一起,并且不同Linux内核之间的端口重用工作方式存在一些相当特殊的差异。
我在openpgm
仓库中添加了一些代码,以解决与rhel7
有关的问题
https://github.com/steve-o/openpgm/pull/52
詹姆斯