Beginning Python Chapter 27
来源:互联网 发布:最美的句子知乎 编辑:程序博客网 时间:2024/05/16 01:21
First, I created the simple_node file, and as for I am using the Python 3.0, so there are several changes in the reference libs.
1. In 3.0, we use the xmlrpc lib and there are two module client and server under it. So normally, we should code as 'from xmlrpc import client' and from xmlrpc import server'.
2. In 3.0, the urlparse method has been included in the parse module under the urllib. Thus, we could use 'from urllib import parse' sentence.
3. For single underscore, it means it is a protected object and for double underscore, it means it is a private object which is more strict than single underscore when it is used.
4. After coding by using the cmd as the interface, you need to add the double quote mark when you refer to a folder name including blank, such as <client.py "D:/Python Program/Chapter27/file1/test.txt" "D:/Python Program/Chapter27/file1" http://localhost:4242
client_f.py
from xmlrpc import server, clientfrom xmlrpc.client import Faultfrom cmd import Cmdfrom random import choicefrom string import ascii_lowercasefrom server_f import Node, UNHANDLEDfrom threading import Threadfrom time import sleepimport sysHEAD_START = 0.1 #SecondsSECRET_LENGTH = 100def randomString(length): """ 返回给定长度的由字母组成的随机字符串。 """ chars = [] letters = ascii_lowercase[:26] while length > 0: length -= 1 chars.append(choice(letters)) return ''.join(chars)class Client(Cmd): """ Node类的简单的基于文本的界面。 """ prompt = '>' def __init__(self, url, dirname, urlfile): """ 设定url、dirname和urlfile,并且在单独的线程中启动Node服务器。 """ Cmd.__init__(self) self.secret = randomString(SECRET_LENGTH) n = Node(url, dirname, self.secret) t = Thread(target=n._start) t.setDaemon(1) t.start() #让服务器先启动 sleep(HEAD_START) self.server = client.ServerProxy(url) for line in open(urlfile): line = line.strip() self.server.hello(line) def do_fetch(self, arg): "调用服务器的fetch方法" try: self.server.fetch(arg, self.secret) except Fault as f: if f.faultCode != UNHANDLED: raise print("Couldn't find the file", arg) def do_exit(self, arg): "退出程序" print() sys.exit() do_EOF = do_exitdef main(): urlfile, directory, url = sys.argv[1:] client = Client(url, directory, urlfile) client.cmdloop()if __name__ == '__main__': main()
from xmlrpc import serverfrom os.path import join, isfile, abspathfrom urllib import parsefrom xmlrpc.server import Faultimport sysserver.SimpleXMLRPCServer.allow_reuse_address = 1MAX_HISTORY_LENGTH = 6UNHANDLED = 100ACCESS_DENIED = 200class UnhandledQuery(Fault): """ 表示无法处理的查询的异常。 """ def __init__(self, message="Couldn'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(dir, name): """ 检查给定的目录中是否有给定的文件名。 """ dir = abspath(dir) name = abspath(name) return name.startswith(join(dir,''))def getPort(url): '用URL提取端口' name = parse.urlparse(url)[1] parts = name.split(':') return int(parts[-1])class Node: """ P2P网络中的节点。 """ 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, query, secret): """ 用于让节点找到文件并下载。 """ if secret != self.secret: raise AccessDenied result = self.query(query) f = open(join(self.dirname, query), 'w') f.write(result) f.close() return 0 def _start(self): """ 内部使用,用于启动XMLRPC服务器。 """ s = server.SimpleXMLRPCServer(("",getPort(self.url)), logRequests=False) s.register_instance(self) s.serve_forever() def _handle(self, query): dir = self.dirname name = join(dir, query) if not isfile(name): raise UnhandledQuery if not inside(dir, name): raise AccessDenied return open(name).read() def _broadcast(self, query, history): """ 内部使用,用于将查询广播到所有已知节点。 """ for other in self.known.copy(): if other in history: continue try: s = client.ServerProxy(other) return s.query(query, history) except Fault as f: if f.faultCode == UNHANDLED: pass else: self.known.remove(other) except: self.known.remove(other) raise UnhandledQuerydef main(): url, directory, secret = sys.argv[1:] n = Node(url, directory, secret) n._start()if __name__ == '__main__': main()
- Beginning Python Chapter 27
- Beginning Python Chapter 21
- Beginning Python Chapter 22
- Beginning Python Chapter 25
- Beginning Python Chapter 26
- Beginning Python Chapter 28
- beginning python summary chapter 3 - 使用字符串
- beginning python summary chapter 4 - 字典
- beginning python summary chapter 6 - 抽象
- beginning python summary chapter 2 - 列表和元组
- beginning python summary chapter 5 - 条件,循环和其他语句
- Chapter 7 Beginning CXControl
- Beginning Python
- Beginning Linux Programming chapter 3
- Beginning Linux Programming chapter 4
- Beginning Linux Programming chapter 7
- Beginning Linux Programming chapter 11
- Beginning Linux Programming chapter 13
- 创建你第一个SharePoint 2010 应用程序----完整推荐总结
- jqm视频播放器,html5视频播放器,html5音乐播放器,html5播放器,video开发demo,html5视频播放示例,html5手机视频播放器
- A
- Ruby Regexp using gsub is there an equivalent to self keyword?
- SVN update Failed . Locked
- Beginning Python Chapter 27
- cocos2dx挖掘
- IntelliJ IDEA 代码提示的问题
- 判断大端或小端
- 读mybatis源码之二:构建SqlSession逻辑
- 有用的开源库支持
- 三分搜索——初见
- 装大神开博客
- 多态(动态绑定)