加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

用XML_RPC实现P2P

发布时间:2020-12-17 17:24:17 所属栏目:Python 来源:网络整理
导读:今天PHP站长网 52php.cn把收集自互联网的代码分享给大家,仅供参考。 # -*- coding: utf-8 -*-from xmlrpclib import ServerProxy,Faultfrom os.path import join,isfile,abspathfrom SimpleXMLRPCServer import SimpleXM

以下代码由PHP站长网 52php.cn收集自互联网

现在PHP站长网小编把它分享给大家,仅供参考

# -*- 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()

以上内容由PHP站长网【52php.cn】收集整理供大家参考研究

如果以上内容对您有帮助,欢迎收藏、点赞、推荐、分享。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读