2016-07-03 4 views
1

Raspbian 8 (jessie)을 실행하는 Raspberry Pi에서 사용자 지정 이벤트 루프가있는 pyro4 서버를 실행하려고합니다. socket.gethostname()에서 얻은 호스트 이름, 특히 'raspberrypi'를 사용하여 네임 서버를 만들면 클라이언트 스크립트에서 네임 서버를 찾을 수 없습니다. 'localhost'를 호스트 이름으로 사용하면 클라이언트 스크립트에서 호스트 이름을 찾을 수 있습니다./localhost는 분명히 127.0.0.1에 바인드되지만/etc/hosts에서 'raspberrypi'는 127.0.1.1로 바인드됩니다. 나는이 두 주소가 모두 루프백 인터페이스에 연결되어 있다고 생각했기 때문에 왜 다른 하나가 작동해야하는지 이해하지 못합니다.pyro4가 127.0.1.1에서 nameserver를 찾지 못하고 127.0.0.1에서 성공하지 못하는 이유는 무엇입니까?

pyro4 코드를 조사한 결과 Pyro4.naming.py의 l.463처럼 보이지만 proxy.ping() 호출은 127.0.1.1에서는 실패하지만 127.0.0.1에서는 실패합니다. , 이것은 궁극적으로 이전 주소로 실패를 유발하는 것입니다. Pyro의 전문가가 아니기 때문에이 동작이 예상되는지 여부가 명확하지 않습니다. 이견있는 사람? 데비안의 대부분의 (모든?) 맛은이 두 주소에 대해/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 

답변

0

파이의 이름 서버 조회는 두 가지에 의존 :

  • 방송 조회
  • 호스트 이름/IP 주소로
  • 직접 조회

당신이 바인딩에 루프백 어댑터를 사용할 때 첫 번째는 사용할 수 없습니다 네임 서버 온 (루프백은 브로드 캐스트 소켓을 지원하지 않습니다). 그래서 우리에게는 두 번째 것이 남아 있습니다. 당신의 질문에 대한 대답은 간단합니다. 즉, NS_HOST 설정 항목의 값에 대한 직접 조회가 수행됩니다.이 항목은 기본적으로 'localhost'로 설정되어 있습니다. localhost는 127.0.0.1로 연결되므로 절대로 127.0.1.1에 연결되지 않습니다.

제안 : 0.0.0.0 또는 ""(빈 호스트 이름)에 네임 서버를 바인드하면 브로드 캐스트 응답을 시작할 수 있어야합니다. 그러면 고객이 문제를 찾지 않아도됩니다.

또는 클라이언트의 NS_HOST를 127.0.1.1 (또는 상자의 호스트 이름)으로 설정하면 127.0.1.1에 바인드 된 경우 이름 서버도 찾을 수 있어야합니다.

관련 문제