用XML_RPC实现P2P
发布时间:2020-05-24 23:48:55 所属栏目:Python 来源:互联网
导读:用XML_RPC实现P2P
|
下面是脚本之家 jb51.cc 通过网络收集整理的代码片段。 脚本之家小编现在分享给大家,也给大家做个参考。 # -*- coding: utf-8 -*-
from xmlrpclib import ServerProxy,Fault
from os.path import join,isfile,abspath
from SimpleXMLRPCServer import SimpleXMLRPCServer
from urlparse import urlparse
import sys
import xmlrpclib
SimpleXMLRPCServer.allow_reuse_address = 1
#避免循环请求和长链请求。之所以用6是采用了六度分隔的原理
MAX_HISTORY_LENGTH = 6
UNHANDLED = 100
ACCESS_DENIED = 200
class UnhandledQuery(Fault):
def __init__(self,message="Counldn't handle the query"):
Fault.__init__(self,UNHANDLED,message)
class AccessDenied(Fault):
def __init__(self,message='Access denied'):
Fault.__init__(self,ACCESS_DENIED,message)
def inside(dirs,name):
the_dir = abspath(dirs)
name = abspath(name)
return name.startswith(join(the_dir,''))
def getPort(url):
name = urlparse(url)[1]
parts = name.split(':')
return int(parts[-1])
class Node:
def __init__(self,url,dirname,secret):
self.url = url
self.dirname = dirname
self.secret = secret
self.known = set()
def query(self,query,history=[]):
try:
return self._handle(query)
except UnhandledQuery:
history = history + [self.url]
if len(history) >= MAX_HISTORY_LENGTH: raise
return self._broadcast(query,history)
def hello(self,other):
self.known.add(other)
return 0
def fetch(self,secret):
"""找到并下载资源"""
if secret != self.secret: raise AccessDenied
result = self.query(query)
f = open(join(self.dirname,query),'wb')
f.write(result.data)
f.close()
return 0
def _start(self):
#启动XML_RPC服务器
s = SimpleXMLRPCServer(("",getPort(self.url)),logRequests=False)
s.register_instance(self)
s.serve_forever()
def _handle(self,query):
"""处理请求"""
name = join(self.dirname,query)
if not isfile(name): raise UnhandledQuery
if not inside(self.dirname,name): raise AccessDenied
return xmlrpclib.Binary(open(name,'rb').read())
def _broadcast(self,history):
"""将查询广播到所有已知的Node"""
for other in self.known.copy():
if other in history: continue
try:
s = ServerProxy(other)
return s.query(query,history)
except Fault,f:
if f.faultCode == UNHANDLED: pass
else: self.known.remove(other)
except:
self.known.remove(other)
raise UnhandledQuery
def main():
url,directory,secret = sys.argv[1:]
n = Node(url,secret)
n._start()
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt: sys.exit()
以上是脚本之家(jb51.cc)为你收集整理的全部代码内容,希望文章能够帮你解决所遇到的程序开发问题。 如果觉得脚本之家网站内容还不错,欢迎将脚本之家网站推荐给程序员好友。 (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
