2

別の場所から何かにpingを実行したい場合は、pingコマンドラインツールをPythonにラップし、pyro4prcライブラリを使用して呼び出します。

私はPythonPyro4ネームサーバーを持っています

import Pyro4
Pyro4.config.COMPRESSION = True
Pyro4.naming.startNSloop("ipofnameserver")

そして単純なpingサーバー:

class Pinger(object):
    def ping(self, host):
        return subprocess.check_output(["ping", host, "-c 4"])

pinger = Pinger()

daemon = Pyro4.Daemon()                 # make a Pyro daemon
ns  = Pyro4.locateNS(host = "ipofnameservre", port=9090) # find the name server
uri = daemon.register(pinger)   # register the greeting object as a Pyro object
print ns.register("location1", uri) 
print "Ready. Object uri =", uri      # print the uri so we can use it in the client later
daemon.requestLoop()    

pingserverが2つしかない限り、すべて問題ありませんが、3つ目の名前サーバーを追加すると、応答が停止します。もちろん、すべてのpingserverには一意の名前があります。

たとえば、サーバーの可用性を確認したいと思います。

ns  = Pyro4.locateNS(host = "nameserverip", port=9090)
names = ns.list().keys()
print names
print ns.list()
for n in names:
    if n == 'Pyro.NameServer': continue
    proxy = Pyro4.Proxy("PYRONAME:"+n)
    try:
        print n, proxy._Proxy__pyroCreateConnection()
    except:
        print "offline"

これは2つのpingserverで機能しますが、3つでは何かを待つだけです。このスクリプトのトレースバックはctrl+Cで終了しました。

   ns  = Pyro4.locateNS(host = "nameserverip", port=9090)
  File "/usr/local/lib/python2.7/dist-packages/Pyro4/naming.py", line 319, in locateNS
    proxy.ping()
  File "/usr/local/lib/python2.7/dist-packages/Pyro4/core.py", line 146, in __call__
    return self.__send(self.__name, args, kwargs)
  File "/usr/local/lib/python2.7/dist-packages/Pyro4/core.py", line 250, in _pyroInvoke
    self.__pyroCreateConnection()
  File "/usr/local/lib/python2.7/dist-packages/Pyro4/core.py", line 312, in __pyroCreateConnection
    msgType, flags, seq, data = MessageFactory.getMessage(conn, None)
  File "/usr/local/lib/python2.7/dist-packages/Pyro4/core.py", line 665, in getMessage
    headerdata = connection.recv(cls.HEADERSIZE)
  File "/usr/local/lib/python2.7/dist-packages/Pyro4/socketutil.py", line 323, in recv
    return receiveData(self.sock, size)
  File "/usr/local/lib/python2.7/dist-packages/Pyro4/socketutil.py", line 104, in receiveData
    data=sock.recv(size, socket.MSG_WAITALL)

straceは次のことを示しています。

socket(PF_INET、SOCK_STREAM、IPPROTO_IP)= 3 fcntl(3、F_GETFL)
= 0x2(フラグO_RDWR)fcntl(3、F_SETFL、O_RDWR)= 0 connect(3、{sa_family = AF_INET、sin_port = htons(9090)、sin_addr = inet_addr( "ipofnameserver")}、16)= 0 setsockopt(3、SOL_SOCKET、SO_KEEPALIVE、[1]、4)= 0 recvfrom(3、

次の例も、名前をpyro_uriに解決できないため、機能していません。これは、前の例のように待機しているだけだからです。この例の興味深い点は、すべてのリモートpingserverの名前を含むflsを出力することです。次に、4番目のpingserverを追加すると、登録されているpingserverの名前を出力することすらできません。

def _ping((host, firing_location)):
    pinger = Pyro4.Proxy("PYRONAME:" + firing_location)
    return pinger.ping(host)

def ping(host):
    ns  = Pyro4.locateNS(host = "178.209.52.240", port=9090)
    names = ns.list().keys()
    fls = []
    for name in names:
        if name == 'Pyro.NameServer': continue
        fls.append(name)
    print fls
    p = Pool(len(fls))
    jobs = p.map(_ping, zip([host]*len(fls), fls) )
    for j in jobs:
        print j.split("/")[-3], "±", j.split("/")[-1][:-1]
    return jobs

私は2日間苦労していて、コードの何が問題になっているのかわかりません。

4

0 に答える 0