为什么 pyro4 无法在 127.0.1.1 下定位名称服务器但在 127.0.0.1 下成功?
Why does pyro4 fail to locate nameserver under 127.0.1.1 but succeed with 127.0.0.1?
我正在尝试 运行 带有自定义事件循环的 pyro4 服务器 Raspberry Pi 运行ning Raspbian 8 (jessie)。当我使用从 socket.gethostname() 获得的主机名创建名称服务器时,特别是 'raspberrypi',我的客户端脚本找不到名称服务器。当我使用 'localhost' 作为主机名时,我的客户端脚本能够找到主机名。在/etc/hosts中,'raspberrypi'绑定到127.0.1.1,而'localhost'显然绑定到127.0.0.1。我原以为这两个地址都绑定到环回接口,所以我不明白为什么一个应该工作而另一个不工作。
对于它的价值,在对 pyro4 代码进行一些挖掘之后,它看起来像 Pyro4.naming.py 的 l.463,对 proxy.ping() 的调用失败了 127.0.1.1 但不是127.0.0.1,这最终是触发前一个地址失败的原因。不是 Pyro 的专家,不清楚这种行为是否是预期的。有什么想法吗?我认为这一定是一个常见问题,因为大多数(所有?)Debian 版本在 /etc/hosts 中为这两个地址包含单独的行。
我在下面附上了重现问题的代码。这基本上只是 pyro 附带的 "eventloop" 示例的略微修改版本。
server.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()
client.py:
from __future__ import print_function
import Pyro4
proxy=Pyro4.core.Proxy("PYRONAME:example.embedded.server")
print("count = %d" % proxy.get_count())
MotorControl.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
Pyro 的名称服务器查找依赖于两件事:
- 广播查找
- 直接查找 hostname/ip-address
当您使用环回适配器绑定名称服务器时,第一个不可用(环回不支持广播套接字)。所以我们只剩下第二个了。
您的问题的答案很简单:直接查找是根据 NS_HOST 配置项的值完成的,默认设置为 'localhost'。由于本地主机解析为 127.0.0.1,因此它永远不会连接到 127.0.1.1。
建议:在 0.0.0.0 或“”(空主机名)上绑定名称服务器,它也应该能够启动广播响应程序。这样您的客户就不会遇到任何问题。
或者,只需为您的客户将 NS_HOST 设置为 127.0.1.1(或您机器的主机名),如果名称服务器绑定在 127.0.1.1
我正在尝试 运行 带有自定义事件循环的 pyro4 服务器 Raspberry Pi 运行ning Raspbian 8 (jessie)。当我使用从 socket.gethostname() 获得的主机名创建名称服务器时,特别是 'raspberrypi',我的客户端脚本找不到名称服务器。当我使用 'localhost' 作为主机名时,我的客户端脚本能够找到主机名。在/etc/hosts中,'raspberrypi'绑定到127.0.1.1,而'localhost'显然绑定到127.0.0.1。我原以为这两个地址都绑定到环回接口,所以我不明白为什么一个应该工作而另一个不工作。
对于它的价值,在对 pyro4 代码进行一些挖掘之后,它看起来像 Pyro4.naming.py 的 l.463,对 proxy.ping() 的调用失败了 127.0.1.1 但不是127.0.0.1,这最终是触发前一个地址失败的原因。不是 Pyro 的专家,不清楚这种行为是否是预期的。有什么想法吗?我认为这一定是一个常见问题,因为大多数(所有?)Debian 版本在 /etc/hosts 中为这两个地址包含单独的行。
我在下面附上了重现问题的代码。这基本上只是 pyro 附带的 "eventloop" 示例的略微修改版本。
server.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()
client.py:
from __future__ import print_function
import Pyro4
proxy=Pyro4.core.Proxy("PYRONAME:example.embedded.server")
print("count = %d" % proxy.get_count())
MotorControl.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
Pyro 的名称服务器查找依赖于两件事:
- 广播查找
- 直接查找 hostname/ip-address
当您使用环回适配器绑定名称服务器时,第一个不可用(环回不支持广播套接字)。所以我们只剩下第二个了。 您的问题的答案很简单:直接查找是根据 NS_HOST 配置项的值完成的,默认设置为 'localhost'。由于本地主机解析为 127.0.0.1,因此它永远不会连接到 127.0.1.1。
建议:在 0.0.0.0 或“”(空主机名)上绑定名称服务器,它也应该能够启动广播响应程序。这样您的客户就不会遇到任何问题。
或者,只需为您的客户将 NS_HOST 设置为 127.0.1.1(或您机器的主机名),如果名称服务器绑定在 127.0.1.1