为什么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地址,以其数字表示。