0

In this code the Subscriber ( in subscriber.cpp code ) socket binds to port 5556.

It receives updates/messages from publisher ( in subscriber.cpp ), and publisher socket connects to the subscriber at 5556 and sends updates/messages to it.

I know that convention is to .bind() a publisher and not to call .connect() on it. But by theory every socket type can .bind() or .connect().

But, both the codes give zmq error when run. Why?

This is CPP code.

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;
}
user3666197
  • 1
  • 6
  • 50
  • 92
Ayush
  • 880
  • 1
  • 9
  • 21
  • 1
    `theory every socket type can bind or connect` no - udp doesn't make connections. You bind to a port on both sides and send data to the other end... nothing ensures that the data will be received; or will tell you that it is – UKMonkey Mar 07 '18 at 15:12
  • Okay. But please tell why above code fails.@UKMonkey – Ayush Mar 07 '18 at 15:15
  • 1
    I'd have to install zeromq; take your code; and then follow the steps in https://ericlippert.com/2014/03/05/how-to-debug-small-programs/ It would help if you said what the error was; but learning to debug your own programs is somewhat essential before attempting to do such complex tasks as this – UKMonkey Mar 07 '18 at 15:17
  • Would you kindly also post the ZeroMQ version + zmq_error number + where it has actually happened? ( **all the normal debugging details** ) – user3666197 Mar 07 '18 at 16:29
  • 1
    Version : 4.2.3 After I run the program ,this is the output that I get: for publisher.cpp "terminate called after throwing an instance of 'zmq::error_t' what(): Invalid argument Aborted" For subscriber.cpp:" terminate called after throwing an instance of 'zmq::error_t' what(): No such device Aborted" – Ayush Mar 08 '18 at 04:22
  • UPDATE: The code is working when I changed the line - subscriber.bind("tcp://localhost:5556"); to subscriber.bind("tcp://*:5556"); and publisher.connect("tcp://*:5556"); to publisher.connect("tcp://localhost:5556"); – Ayush Mar 08 '18 at 04:25

2 Answers2

1

No, there is no problem in reversed .bind()/.connect()

This principally works fine.

Yet, the PUB/SUB Formal Archetype is subject to a so called late-joiner syndrome.

Without thorough debugging details, as were requested above, one may just repeat general rules of thumb:

In newer API versions one may
add rc = <aSocket>.setsockopt( ZMQ_CONFLATE, 1 ); assert( rc & "CONFLATE" );
add rc = <aSocket>.setsockopt( ZMQ_IMMEDIATE, 1 ); assert( rc & "IMMEDIATE" );
and so forth,
all that to better tune the context-instance + socket-instance attributes, so as to minimise the late-joiner syndrome effects.

user3666197
  • 1
  • 6
  • 50
  • 92
  • UPDATE: The code is working when I changed the line - subscriber.bind("tcp://localhost:5556"); to subscriber.bind("tcp://*:5556"); and publisher.connect("tcp://*:5556"); to publisher.connect("tcp://localhost:5556"); – Ayush Mar 08 '18 at 04:27
  • 1
    Right, error traces may look mystic, but clear - the 1st is related to symbolic-name translation, the 2nd is a residual nonsense from a SLOC being manually changed / edited from .bind() method, where it had sense to .connect(), where wildcard expansion lost the sense. **Glad you have debugged down to the root cause.** – user3666197 Mar 08 '18 at 04:34
1

There is no problem with reversed bind()/connect(). The code is working when I changed the line - subscriber.bind("tcp://localhost:5556"); to subscriber.bind("tcp://:5556"); and publisher.connect("tcp://:5556"); to publisher.connect("tcp://localhost:5556");

Ayush
  • 880
  • 1
  • 9
  • 21