I put together the following program to show the issue. It seems if the option ZMQ_IPV4ONLY is set to 0 (to enable IPV6), then ZMQ as running on OS X allows two sockets to bind to the same port, provided the address used is 0.0.0.0. For instance, as in the test program, I can construct two sockets, both bound to “tcp://0.0.0.0:9998”, as long as ZMQ_IPV4ONLY is set to 0. If the option is set to 1, or the test program is run in Linux, centos65…. then things work as expected.
Uname of ‘broken’ OS X system: Darwin khenrick.ddns.nominum.com<http://khenrick.ddns.nominum.com> 14.0.0 Darwin Kernel Version 14.0.0: Fri Sep 19 00:26:44 PDT 2014; root:xnu-2782.1.97~2/RELEASE_X86_64 x86_64 Uname of ‘working’ Linux system: Linux vagrant-centos65 2.6.32-431.5.1.el6.x86_64 #1 SMP Wed Feb 12 00:41:43 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux #include <iostream> #include <random> #include <zmq.hpp> using namespace std; static const char *DEFAULT_ADDR = "tcp://0.0.0.0:9998"; /*---------------------------------------------------------------------- * ROUTER socket *----------------------------------------------------------------------*/ zmq::socket_t *init_socket(zmq::context_t &context, std::string address, int v4only) { zmq::socket_t *socket_ptr = new zmq::socket_t(context, ZMQ_ROUTER); cout << "Binding router socket..." << endl; socket_ptr->setsockopt(ZMQ_IDENTITY, address.data(), address.size()); int timeout(0); socket_ptr->setsockopt(ZMQ_RCVTIMEO, &timeout, sizeof(timeout)); socket_ptr->setsockopt(ZMQ_SNDTIMEO, &timeout, sizeof(timeout)); socket_ptr->setsockopt(ZMQ_IPV4ONLY, &v4only, sizeof(v4only)); socket_ptr->bind(address.c_str()); return socket_ptr; } void test_two_socks(int v4only) { zmq::context_t ctx; zmq::socket_t *zmq_ptr_a = init_socket(ctx, DEFAULT_ADDR, v4only); zmq::socket_t *zmq_ptr_b = init_socket(ctx, DEFAULT_ADDR, v4only); if (zmq_ptr_a != nullptr) { cout << "Bye A!" << endl; delete(zmq_ptr_a); } if (zmq_ptr_b != nullptr) { cout << "Bye B!" << endl; delete(zmq_ptr_b); } } /*********************************************************************** * Main entry point. ***********************************************************************/ int main (int argc, char ** argv) { std::cout << "This succeeds" << std::endl; test_two_socks(0); std::cout << "This fails" << std::endl; test_two_socks(1); return 0; }
_______________________________________________ zeromq-dev mailing list zeromq-dev@lists.zeromq.org http://lists.zeromq.org/mailman/listinfo/zeromq-dev