2011-05-16 117 views
53

此代码的伟大工程:为什么zeromq不能在localhost上运行?

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) 

但这个代码 *工作:

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) 

它提出了这样的错误:

ZMQError: No such device

为什么不能zeromq使用localhost接口?

它只在同一台机器上的IPC上工作吗?

回答

33

的问题是在行:

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

尝试改变:

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

我喜欢用像127.0.0.101更高的地址,并改变它每个应用程序。比IPC插座更清洁。 – 2011-07-01 01:39:03

+17

@fdb是的,这解决了问题,但并不能解释为什么!它需要[更多解释](http://stackoverflow.com/a/8958414/462302)。 – aculich 2012-01-22 02:12:49

126

由于@fdb指出:

的问题是在行:

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

尝试更改为:

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

但是这需要更多的解释来理解为什么。

zmq_bind的文档说明(粗体重点煤矿):

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.

由于您的示例使用TCP作为传输协议,我们的zmq_tcp文档中查找发现(再次,大胆重点煤矿):

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.

因此,如果您不使用通配符或接口名称,那么这意味着您必须使用数字形式的IPv4地址(而不是DNS名称)。

注意,这仅适用于使用zmq_bind!在另一方面,这是完全正常使用,因为在文档中进行zmq_tcp稍后讨论与zmq_connect DNS名称:

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.
+3

这是一个奇怪的实现。 – huggie 2014-12-07 05:58:19

+0

啊一个非正交的API – RichardOD 2017-06-12 15:50:52

相关问题