为什么pyro4在127.0.1.1下找不到nameserver,而在127.0.0.1下却成功?

2024-06-01 13:12:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我尝试运行一个pyro4服务器,在运行Raspbian8(jessie)的Raspberry Pi上运行自定义事件循环。当我使用从套接字.gethostname(),特别是“raspberrypi”,我的客户端脚本找不到名称服务器。当我使用'localhost'作为主机名时,我的客户机脚本能够找到主机名。在/etc/hosts中,“raspberrypi”绑定到127.0.1.1,而“localhost”显然绑定到了127.0.0.1。我原以为这两个地址都绑定到环回接口,所以我不明白为什么一个应该工作而另一个不能工作。在

值得一提的是,在对pyro4代码进行了一些挖掘之后,它看起来像是pyro4的l.463。命名.py,呼叫代理.ping()在使用127.0.1.1时失败,但在使用127.0.0.1时失败,而这正是触发前一个地址失败的根本原因。作为一个火专家,还不清楚这种行为是否在预料之中。有什么想法吗?我想这一定是一个常见的问题,因为大多数(全部?)Debian的风格在/etc/hosts中为这两个地址包含单独的行。在

我在下面附上了代码,重现了这个问题。这基本上只是pyro附带的“eventloop”示例的一个稍微修改的版本。在

在服务器.py公司名称:

import socket
import select
import sys
import Pyro4.core
import Pyro4.naming

import MotorControl

Pyro4.config.SERVERTYPE="thread"
hostname=socket.gethostname()

print("initializing services... servertype=%s" % Pyro4.config.SERVERTYPE)
# start a name server with broadcast server as well
nameserverUri, nameserverDaemon, broadcastServer = Pyro4.naming.startNS(host=hostname)
pyrodaemon=Pyro4.core.Daemon(host=hostname)

motorcontroller = MotorControl.MotorControl()
serveruri=pyrodaemon.register(motorcontroller)
nameserverDaemon.nameserver.register("example.embedded.server",serveruri)

# below is our custom event loop.
while True:
    nameserverSockets = set(nameserverDaemon.sockets)
    pyroSockets = set(pyrodaemon.sockets)
    rs = []
    rs.extend(nameserverSockets)
    rs.extend(pyroSockets)

    rs,_,_ = select.select(rs,[],[], 0.001)

    eventsForNameserver=[]
    eventsForDaemon=[]
    for s in rs:
        if s in nameserverSockets:
            eventsForNameserver.append(s)
        elif s in pyroSockets:
            eventsForDaemon.append(s)
    if eventsForNameserver:
        nameserverDaemon.events(eventsForNameserver)
    if eventsForDaemon:
        pyrodaemon.events(eventsForDaemon)

    motorcontroller.increment_count()

nameserverDaemon.close()
broadcastServer.close()
pyrodaemon.close()

在客户端.py公司名称:

^{pr2}$

在电机控制.py在

class MotorControl(object):
    def __init__(self):
        self.switches = 0

    def get_count(self):
        return self.switches

    def increment_count(self):
        self.switches = self.switches + 1

错误:

Traceback (most recent call last):
  File "pyroclient.py", line 5, in <module>
    print("count = %d" % proxy.get_count())
  File "/usr/local/lib/python2.7/dist-packages/Pyro4/core.py", line 248, in __getattr__
    self._pyroGetMetadata()
  File "/usr/local/lib/python2.7/dist-packages/Pyro4/core.py", line 548, in _pyroGetMetadata
    self.__pyroCreateConnection()
  File "/usr/local/lib/python2.7/dist-packages/Pyro4/core.py", line 456, in __pyroCreateConnection
    uri = resolve(self._pyroUri, self._pyroHmacKey)
  File "/usr/local/lib/python2.7/dist-packages/Pyro4/naming.py", line 548, in resolve
    nameserver = locateNS(uri.host, uri.port, hmac_key=hmac_key)
  File "/usr/local/lib/python2.7/dist-packages/Pyro4/naming.py", line 528, in locateNS
    raise e
Pyro4.errors.NamingError: Failed to locate the nameserver

Tags: inpycoreimportselflibusrlocal
1条回答
网友
1楼 · 发布于 2024-06-01 13:12:42

Pyro服务器的查找依赖于两个方面:

  • 广播查找
  • 按主机名/ip地址直接查找

当使用环回适配器绑定名称服务器时,第一个不可用(环回不支持广播套接字)。所以剩下第二个了。 您的问题的答案很简单:直接查找NS_HOST config项的值,默认设置为“localhost”。当localhost解析为127.0.0.1时,它将永远不会连接到127.0.1.1。在

建议:将名称服务器绑定到0.0.0.0或“”(空主机名)上,它应该能够启动广播响应程序。那么你的客户就不会有任何问题找到它。在

或者,只需为您的客户机将NS_HOST设置为127.0.1.1(或您的主机名),如果名称服务器绑定在127.0.1.1上,那么他们也应该能够找到名称服务器

相关问题 更多 >