为什么zeromq在本地主机上无法工作?

75

这段代码运行得非常好:

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不能使用本地主机接口吗?

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

2个回答

195

正如@fdb所指出的:

问题出现在以下行:

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

尝试更改为:
subscriber.bind("tcp://127.0.0.1:5555")

然而,这需要更多的解释才能理解为什么。 zmq_bind文档解释道(重点在于加粗):
“endpoint参数是一个由两部分组成的字符串:transport://address。transport部分指定要使用的底层传输协议。地址部分的含义特定于所选的底层传输协议。”
由于您的示例将tcp作为传输协议,因此我们查看zmq_tcp文档以了解(同样,重点在于加粗):
使用zmq_bind()函数为套接字分配本地地址时,如果使用tcp传输协议,则endpoint应被解释为一个接口,后跟要使用的TCP端口号。可以通过以下任一方式指定接口: * 通配符*,表示所有可用接口。 * 分配给接口的主要IPv4地址,以其数字表示形式表示。 * 操作系统定义的接口名称。
因此,如果未使用通配符或接口名称,则必须使用数字形式的IPv4地址(而不是DNS名称)。
请注意,这仅适用于使用zmq_bind()!另一方面,在zmq_tcp的文档中稍后讨论,可以完全使用DNS名称与zmq_connect()函数配合使用。
使用zmq_connect()函数连接tcp传输的套接字时,端点应被解释为对等地址,后跟冒号和要使用的TCP端口号。对等地址可以通过以下任一方式指定:
  • 对等方的DNS名称。
  • 对等方的IPv4地址,以其数字表示形式呈现。

12
这是一个奇怪的实现。 - huggie
1
啊,一个非正交 API。 - RichardOD
1
这是由底层套接字API决定的,它要求绑定到特定的网络接口(或所有接口),而主机名->接口不是一对一的映射。相反,与具有多个地址的主机名建立连接是一个明确定义的操作。 - joshperry

53
问题出现在这一行:
subscriber.bind("tcp://localhost:5555")
尝试更改为:
subscriber.bind("tcp://127.0.0.1:5555")

我喜欢使用像127.0.0.101这样的高地址,并根据应用程序进行变化。比IPC套接字更干净。 - Michael Dillon
20
是的,那个解决了问题,但没有解释为什么!需要更多的解释 - aculich

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接