为什么zeromq不能在localhost上运行?

时间:2011-05-16 22:07:47

标签: python localhost zeromq

此代码效果很好:

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:没有这样的设备

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

它是否仅适用于同一台机器上的IPC?

2 个答案:

答案 0 :(得分:153)

正如@fdb所指出的那样:

问题在于:

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

尝试更改为:

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

然而,理解为什么这需要更多解释。

zmq_bind的文档解释了(大胆强调我的):

  

端点参数是一个由两部分组成的字符串,如下所示:   transport://address transport 部分指定底层证券   要使用的传输协议。 地址部分的含义是具体的   选择的基础传输协议。

由于您的示例使用tcp作为传输协议,因此我们会在zmq_tcp文档中查找(再次强调我的):

  

使用带有的zmq_bind()为套接字分配本地地址时    tcp 传输,端点应解释为接口   然后是冒号和要使用的TCP端口号。

     

可以通过以下任一方式指定接口:

     
      
  • 外卡*,表示所有可用接口。
  •   
  • 分配给接口的主IPv4地址,的数字表示
  •   
  • 操作系统定义的接口名称。
  •   

因此,如果您不使用通配符或接口名称,则表示您必须使用数字形式的IPv4地址(而不是DNS名称)。

注意,这仅适用于zmq_bind的使用!另一方面,使用zmq_connect的DNS名称完全没问题,稍后将在zmq_tcp的文档中讨论:

  

使用zmq_connect()将套接字连接到对等地址时   在tcp传输中,端点应被解释为对等地址   然后是冒号和要使用的TCP端口号。

     

可以通过以下任一方式指定对等地址:

     
      
  • 对等方的DNS名称。
  •   
  • 对等体的IPv4地址,以数字表示。
  •   

答案 1 :(得分:38)

问题在于:

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

尝试更改为:

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