Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't zeromq work on localhost?

This code works great:

import zmq, json, time  def main():     context = zmq.Context()     subscriber = context.socket(zmq.SUB)     subscriber.bind("ipc://test")     subscriber.setsockopt(zmq.SUBSCRIBE, '')     while True:         print subscriber.recv()  def main():     context = zmq.Context()     publisher = context.socket(zmq.PUB)     publisher.connect("ipc://test")     while True:         publisher.send( "hello world" )         time.sleep( 1 ) 

But this code doesn't* work:

import zmq, json, time  def recv():     context = zmq.Context()     subscriber = context.socket(zmq.SUB)     subscriber.bind("tcp://localhost:5555")     subscriber.setsockopt(zmq.SUBSCRIBE, '')     while True:         print subscriber.recv()  def send():     context = zmq.Context()     publisher = context.socket(zmq.PUB)     publisher.connect("tcp://localhost:5555")     while True:         publisher.send( "hello world" )         time.sleep( 1 ) 

It raises this error:

ZMQError: No such device

Why, can't zeromq use localhost interfaces?

Does it only work on IPC on the same machine?

like image 887
user756428 Avatar asked May 16 '11 22:05

user756428


People also ask

Does ZeroMQ use TCP or UDP?

To begin, instead of being stream (TCP), or datagram (UDP) oriented, ZeroMQ communication is message-oriented. This means that if a client socket sends a 150kb message, then the server socket will receive a complete, identical message on the other end without having to implement any explicit buffering or framing.

Where is ZeroMQ used?

We use ZeroMQ to connect mobile devices together into a peer-to-peer mesh. We use it to build back-ends, which can scale from one box to many boxes without code changes.

Is ZeroMQ a TCP?

ZeroMQ supports common messaging patterns (pub/sub, request/reply, client/server and others) over a variety of transports (TCP, in-process, inter-process, multicast, WebSocket and more), making inter-process messaging as simple as inter-thread messaging. This keeps your code clear, modular and extremely easy to scale.

What is a ZeroMQ connection?

ZeroMQ (also spelled ØMQ, 0MQ or ZMQ) is an asynchronous messaging library, aimed at use in distributed or concurrent applications. It provides a message queue, but unlike message-oriented middleware, a ZeroMQ system can run without a dedicated message broker; the zero in the name is for zero broker.

Can I use a DNS name with ZMQ_connect?

On the other hand it is perfectly fine to use a DNS name with zmq_connect as discussed later in the docs for zmq_tcp: When connecting a socket to a peer address using zmq_connect () with the tcp transport, the endpoint shall be interpreted as a peer address followed by a colon and the TCP port number to use. The DNS name of the peer.

How to connect a socket to a peer using ZMQ_connect()?

When connecting a socket to a peer address using zmq_connect () with the tcp transport, the endpoint shall be interpreted as a peer address followed by a colon and the TCP port number to use. The DNS name of the peer. The IPv4 address of the peer, in its numeric representation. That's a weird implementation.

How to assign a local address to a socket using ZMQ_bind?

When assigning a local address to a socket using zmq_bind () with the tcp transport, the endpoint shall be interpreted as an interface followed by a colon and the TCP port number to use. The wild-card *, meaning all available interfaces. The primary IPv4 address assigned to the interface, in its numeric representation.


2 Answers

As @fdb points out:

The problem is at line:

subscriber.bind("tcp://localhost:5555") 

try to change to:

subscriber.bind("tcp://127.0.0.1:5555") 

However this deserves more explanation to understand why.

The documentation for zmq_bind explains (bold emphasis mine):

The endpoint argument is a string consisting of two parts as follows: transport://address. The transport part specifies the underlying transport protocol to use. The meaning of the address part is specific to the underlying transport protocol selected.

Since your example uses tcp as the transport protocol we look in the zmq_tcp documentation to discover (again, bold emphasis mine):

When assigning a local address to a socket using zmq_bind() with the tcp transport, the endpoint shall be interpreted as an interface followed by a colon and the TCP port number to use.

An interface may be specified by either of the following:

  • The wild-card *, meaning all available interfaces.
  • The primary IPv4 address assigned to the interface, in its numeric representation.
  • The interface name as defined by the operating system.

So, if you're not using wild-card or the interface name, then it means you must use an IPv4 address in numeric form (not a DNS name).

Note, this only applies to the use of zmq_bind! On the other hand it is perfectly fine to use a DNS name with zmq_connect as discussed later in the docs for zmq_tcp:

When connecting a socket to a peer address using zmq_connect() with the tcp transport, the endpoint shall be interpreted as a peer address followed by a colon and the TCP port number to use.

A peer address may be specified by either of the following:

  • The DNS name of the peer.
  • The IPv4 address of the peer, in its numeric representation.
like image 153
aculich Avatar answered Sep 25 '22 01:09

aculich


The problem is at line:

subscriber.bind("tcp://localhost:5555") 

try to change to:

subscriber.bind("tcp://127.0.0.1:5555") 
like image 38
fdb Avatar answered Sep 22 '22 01:09

fdb