⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 listing27-1.py

📁 《Beginning Python--From Novice to Professional》 的源码
💻 PY
字号:
from xmlrpclib import ServerProxyfrom os.path import join, isfilefrom SimpleXMLRPCServer import SimpleXMLRPCServerfrom urlparse import urlparseimport sysMAX_HISTORY_LENGTH = 6OK = 1FAIL = 2EMPTY = ''def getPort(url):    'Extracts the port from a URL'    name = urlparse(url)[1]    parts = name.split(':')    return int(parts[-1])class Node:    """    A node in a peer-to-peer network.    """    def __init__(self, url, dirname, secret):        self.url = url        self.dirname = dirname        self.secret = secret        self.known = set()    def query(self, query, history=[]):        """        Performs a query for a file, possibly asking other known Nodes for        help. Returns the file as a string.        """        code, data = self._handle(query)        if code == OK:            return code, data        else:            history = history + [self.url]            if len(history) >= MAX_HISTORY_LENGTH:                return FAIL, EMPTY            return self._broadcast(query, history)    def hello(self, other):        """        Used to introduce the Node to other Nodes.        """        self.known.add(other)        return OK    def fetch(self, query, secret):        """        Used to make the Node find a file and download it.        """        if secret != self.secret: return FAIL        code, data = self.query(query)        if code == OK:            f = open(join(self.dirname, query), 'w')            f.write(data)            f.close()            return OK        else:            return FAIL    def _start(self):        """        Used internally to start the XML-RPC server.        """        s = SimpleXMLRPCServer(("", getPort(self.url)), logRequests=False)        s.register_instance(self)        s.serve_forever()    def _handle(self, query):        """        Used internally to handle queries.        """        dir = self.dirname        name = join(dir, query)        if not isfile(name): return FAIL, EMPTY        return OK, open(name).read()    def _broadcast(self, query, history):        """        Used internally to broadcast a query to all known Nodes.        """        for other in self.known.copy():            if other in history: continue            try:                s = ServerProxy(other)                code, data = s.query(query, history)                if code == OK:                    return code, data            except:                self.known.remove(other)        return FAIL, EMPTYdef main():    url, directory, secret = sys.argv[1:]    n = Node(url, directory, secret)    n._start()if __name__ == '__main__': main()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -