为什么 Zeromq 不能在本地主机上工作?

发布于 2024-11-07 11:11:12 字数 1113 浏览 0 评论 0原文

这段代码工作得很好:

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上使用吗?

This code works great:

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 )

But this code doesn't* work:

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 )

It raises this error:

ZMQError: No such device

Why, can't zeromq use localhost interfaces?

Does it only work on IPC on the same machine?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

黯淡〆 2024-11-14 11:11:12

正如 @fdb 指出的:

问题出在 line:

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

try 更改为:

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

但是,这需要更多解释以理解原因。

zmq_bind 的文档解释了(粗体强调是我的):

endpoint 参数是一个由两部分组成的字符串,如下所示:
运输://地址传输部分指定底层
要使用的传输协议。 地址部分的含义是特定的
到所选的底层传输协议。

由于您的示例使用 tcp 作为传输协议,我们在 zmq_tcp 文档来发现(再次强调我的):

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

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

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

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

注意,这只适用于使用zmq_bind!另一方面,使用 zmq_connect 的 DNS 名称是完全可以的,正如稍后在 zmq_tcp

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

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

  • 对等方的 DNS 名称。
  • 对等方的 IPv4 地址(采用数字表示形式)。

As @fdb points out:

The problem is at line:

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

try to change to:

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

However this deserves more explanation to understand why.

The documentation for zmq_bind explains (bold emphasis mine):

The endpoint argument is a string consisting of two parts as follows:
transport://address. The transport part specifies the underlying
transport protocol to use. The meaning of the address part is specific
to the underlying transport protocol selected.

Since your example uses tcp as the transport protocol we look in the zmq_tcp documentation to discover (again, bold emphasis mine):

When assigning a local address to a socket using zmq_bind() with the
tcp transport, the endpoint shall be interpreted as an interface
followed by a colon and the TCP port number to use.

An interface may be specified by either of the following:

  • The wild-card *, meaning all available interfaces.
  • The primary IPv4 address assigned to the interface, in its numeric representation.
  • The interface name as defined by the operating system.

So, if you're not using wild-card or the interface name, then it means you must use an IPv4 address in numeric form (not a DNS name).

Note, this only applies to the use of zmq_bind! On the other hand it is perfectly fine to use a DNS name with zmq_connect as discussed later in the docs for zmq_tcp:

When connecting a socket to a peer address using zmq_connect() with
the tcp transport, the endpoint shall be interpreted as a peer address
followed by a colon and the TCP port number to use.

A peer address may be specified by either of the following:

  • The DNS name of the peer.
  • The IPv4 address of the peer, in its numeric representation.
陌伤浅笑 2024-11-14 11:11:12

问题出在行:

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

尝试更改为:

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

The problem is at line:

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

try to change to:

subscriber.bind("tcp://127.0.0.1:5555")
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文