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

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

37893 次浏览

问题在于:

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的文档解释(粗体强调我的) :

终点参数是一个由以下两部分组成的字符串: transport://address交通工具部分指定基础的 使用传输协议。 地址部分的含义是特定的 到所选择的底层传输协议

由于您的示例使用 tcp 作为传输协议,因此我们将在 Zmq _ tcp文档中发现(再次强调我的示例) :

当使用 zmq _ bind ()将本地地址分配给套接字时, Tcp 传输时,终点须解释为 < em > 接口 后跟冒号和要使用的 TCP 端口号。

接口可由下列任一方指定:

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

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

注意,这只适用于 zmq_bind的使用!另一方面,在 zmq_connect中使用 DNS 名称是完全可以的,正如后面在 Zmq _ tcp的文档中所讨论的:

当使用 zmq _ connect ()将套接字连接到对等地址时,使用 在 tcp 传输时,端点应解释为对等地址 后跟冒号和要使用的 TCP 端口号。

对等地址可由下列任一方指定:

  • 对等方的 DNS 名称。
  • 对等点的 IPv4地址,以其数字表示形式。