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

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

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

问题在于:

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

尝试改变为:

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

正如@fdb所指出的那样:

问题在于:

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

尝试改变为:

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

但是,这值得更多的解释来理解为什么。

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

端点参数是一个由两部分组成的string,如下所示: transport://address传输部分指定要使用的底层传输协议。 地址部分的含义是特定于所选的底层传输协议。

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

当使用带有tcp传输的zmq_bind()将一个本地地址分配给一个套接字时, 端点将被解释为一个接口,后跟一个冒号和要使用的TCP端口号。

接口可以由以下任何一种指定:

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

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

注意,这只适用于使用zmq_bind ! 另一方面,如zmq_tcp文档中讨论的那样,使用带有zmq_connect的DNS名称是完全正确的 :

当使用带有tcp传输的zmq_connect()将套接字连接到对等地址时,端点将被解释为对等地址,后跟冒号和要使用的TCP端口号。

对等地址可能由以下任一项指定:

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