ZeroMQ: использование транспорта EPGM

Я пытаюсь использовать 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 Заявление в редакцию:

  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 (Ethernet) - inet адрес:10.1.1.8
  2. ib0 (InfiniBand) - inet addr:10.1.3.8
  3. lo (Локальная петля) - inet addr:127.0.0.1

2 ответа

Попробуйте 239.0.0.0/8 IP в вашей привязке:

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

Википедия:

Диапазон 239.0.0.0/8 назначается RFC 2365 для частного использования в организации. Из RFC пакеты, предназначенные для адресов многоадресной рассылки IPv4 с административной областью, не пересекают административно определенные организационные границы, а адреса многоадресной рассылки IPv4 с административной областью назначаются локально и не должны быть глобально уникальными.

Я использовал epgm с zeromq на Linux, и это сложно настроить правильно

Предполагая, что вы используете Linux, читайте ниже, если нет, у меня нет опыта работы с Windows, так что не обращайте внимания:

  1. epgm не работает с адаптером обратной связи в Linux, так что забудьте об этом.
  2. Ваш eth0 должно сработать. Является MCAST определенно включен (проверьте ifconfg)?
  3. Использование порта, порт уже используется?

Я ссылку zeromq с openpgm и есть некоторые довольно специфические различия в том, как повторное использование порта работает между различными ядрами Linux.

Я добавил немного кода в openpgm репо, чтобы исправить мои проблемы с rhel7 https://github.com/steve-o/openpgm/pull/52

Джеймс

Другие вопросы по тегам