2

我试图epgm在我的简单发布者 - 订阅者程序中使用传输,但我无法这样做。据我了解,我无法在bindconnect语句中提供正确的地址字符串。

发布者和订阅者可以在相同或不同的机器上运行。

tcp以下是使用传输并正常工作的必需代码。它使用cppzmqhttps ://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发布者中的声明更改为以下内容:

  1. publisher.bind("epgm://10.1.1.8:5000");
  2. publisher.bind("epgm://224.1.1.1:5000");
  3. publisher.bind("epgm://eth0;224.1.1.1:5000");
  4. publisher.bind("epgm://10.1.1.8;224.1.1.1:5000");
  5. publisher.bind("epgm://localhost:5000");

对于所有 5 种情况,程序都以Assertion failed: false (src/pgm_socket.cpp:165). 对于第 5 种情况 ( 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.

注意机器有以下接口:

  1. eth0(以太网)--inet 地址:10.1.1.8
  2. ib0(InfiniBand) -- inet 地址:10.1.3.8
  3. lo(本地环回)--inet 地址:127.0.0.1
4

2 回答 2

0

239.0.0.0/8在绑定中尝试IP:

publisher.bind("epgm://;239.0.0.1:5000");

维基百科

239.0.0.0/8 范围由 RFC 2365 分配,供组织内私人使用。从 RFC 来看,发往行政范围内的 IPv4 多播地址的数据包不会跨越行政范围内定义的组织边界,行政范围内的 IPv4 多播地址是本地分配的,不必是全球唯一的。

于 2018-07-13T23:31:42.177 回答
0

我在linux上使用epgmzeromq,正确配置很棘手

假设您使用的是 linux,请阅读下面的内容,如果不是我没有使用 Windows 的经验,请忽略:

  1. epgm不适用于 linux 上的环回适配器,所以忘记这一点。
  2. eth0应该工作。MCAST确定启用(检查ifconfg)?
  3. 端口使用情况,端口是否已在使用?

zeromqopenpgm不同的 linux 内核之间的端口重用工作方式存在一些相当特殊的差异。

我在 repo 中添加了一些代码来openpgm解决我与rhel7 https://github.com/steve-o/openpgm/pull/52的问题

詹姆士

于 2018-07-18T09:39:00.697 回答