title: ZeroMQ: Using EPGM transport
body: <p>I am trying to use the <code>epgm</code> transport in my simple publisher-subscriber program, but I am unable to do so. From what I understand, I am unable to supply a correct address string in <code>bind</code> and <code>connect</code> statements.</p>
  
  <p>The publisher and subscriber can be running on same or different machines.</p>
  
  <p>Below is the required code which usees <code>tcp</code> transport and works correctly. It uses <code>cppzmq</code>: <a href="https://github.com/zeromq/cppzmq" rel="nofollow">https://github.com/zeromq/cppzmq</a>.</p>
  
  <p>Publisher code:</p>
  
  <pre><code>#include &lt;zmq.hpp&gt;
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;time.h&gt;
  #include &lt;unistd.h&gt;
  
  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;
  }
  </code></pre>
  
  <p>Subscriber code:</p>
  
  <pre><code>#include &lt;zmq.hpp&gt;
  #include &lt;iostream&gt;
  #include &lt;sstream&gt;
  #include &lt;unistd.h&gt;
  #include &lt;cassert&gt;
  
  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 &lt; 1000; ++i) {
      zmq::message_t update;
      int topic, a, b;
      if(subscriber.krecv(&amp;update, ZMQ_DONTWAIT)) {
        //fprintf(stderr, "size of data received: %zd\n", sizeof(update.data()));
        std::istringstream iss(static_cast&lt;char*&gt;(update.data()));
        iss &gt;&gt; topic &gt;&gt; a &gt;&gt; b;
        assert(a == b);
      }
      else {
        --i;
      }
  
      maxx = a &gt; maxx ? a : maxx;
    }
  
    fprintf(stderr, "maxx = %d\n", maxx);
    return 0;
  }
  </code></pre>
  
  <p><code>krecv</code> method that is used in subscriber:</p>
  
  <pre><code>inline bool krecv (message_t *msg_, int flags_ = 0) {
    int nbytes = zmq_msg_recv (&amp;(msg_-&gt;msg), ptr, flags_);
    if (nbytes &gt;= 0)
      return true;
    if (zmq_errno () == EAGAIN)
      return false;
    return false;
  }
  </code></pre>
  
  <p>I tried changing the <code>bind</code> statement in publisher to following:</p>
  
  <ol>
  <li><code>publisher.bind("epgm://10.1.1.8:5000");</code> </li>
  <li><code>publisher.bind("epgm://224.1.1.1:5000");</code></li>
  <li><code>publisher.bind("epgm://eth0;224.1.1.1:5000");</code></li>
  <li><code>publisher.bind("epgm://10.1.1.8;224.1.1.1:5000");</code></li>
  <li><code>publisher.bind("epgm://localhost:5000");</code></li>
  </ol>
  
  <p>For all 5 cases, the program crashes with <code>Assertion failed: false (src/pgm_socket.cpp:165)</code>. For the 5th case (<code>epgm://localhost:5000</code>), I also receive following warnings along with the crash:</p>
  
  <pre><code>Warn: Interface lo reports as a loopback device.
  Warn: Interface lo reports as a non-multicast capable device.
  </code></pre>
  
  <p>How can I resolve this issue? I am guessing that the address change will be same in both publisher and subscriber?</p>
  
  <p>I am using <code>libpgm 5.2.122</code> with <code>zeromq-4.1.3</code>.</p>
  
  <p>Note that the machine has following interfaces:</p>
  
  <ol>
  <li><code>eth0</code> (Ethernet) -- inet addr:<code>10.1.1.8</code></li>
  <li><code>ib0</code> (InfiniBand) -- inet addr:<code>10.1.3.8</code></li>
  <li><code>lo</code> (Local Loopback) -- inet addr:<code>127.0.0.1</code></li>
  </ol>