TinyP2P如何运行 How tinyp2p works!
来源:互联网 发布:吉吉写作软件mac 编辑:程序博客网 时间:2024/05/19 06:14
TinyP2P被誉为世界上最小的P2P应用,只用15行Python代码实现。
然而在实际使用过程中,却会遇到一些问题,下面来看看这段神奇的代码。
这是一段在网上十分流行的经过别人注释的代码:
#zz from http://www.exonsoft.com/~kochin/TinyP2P/tinyp2p.html# tinyp2p.py 1.0 (documentation at http://freedom-to-tinker.com/tinyp2p.html)# (C) 2004, E.W. Felten# license: http://creativecommons.org/licenses/by-nc-sa/2.0# Annotated by Kochin Chang, Jan. 2005# Usage:# Server - python tinyp2p.py password server hostname portnum [otherurl]# Client - python tinyp2p.py password client serverurl pattern# ar[0] ar[1] ar[2] ar[3] ar[4] ar[5]import sys, os, SimpleXMLRPCServer, xmlrpclib, re, hmac# Import libraries used in the program.# sys : system variables and functions.# os : portable OS dependent functionalities.# SimpleXMLRPCServer : basic XML-RPC server framework.# xmlrpclib : XML-RPC client support.# re : regular expression support.# hmac : RFC 2104 Keyed-Hashing Message Authentication.ar,pw,res = (sys.argv,lambda u:hmac.new(sys.argv[1],u).hexdigest(),re.search)# A multiple assignment.# ar <- sys.argv : the argument list.# pw <- lambda u:hmac.new(sys.argv[1],u).hexdigest() :# a function makes an HMAC digest from a URL.# INPUT: a string, u, which is a URL here.# OUTPUT: a hexdecimal HMAC digest.# DESCRIPTION:# 1. Creates a HMAC object from the URL using network's password,# sys.argv[1], as the key.# 2. Returns a hexdecimal digest of the HMAC object.# res <- re.search : alias for the regular expression search function.pxy,xs = (xmlrpclib.ServerProxy,SimpleXMLRPCServer.SimpleXMLRPCServer)# A multiple assignment.# pxy <- xmlrpclib.ServerProxy : alias for the ServerProxy class.# xs <- SimpleXMLRPCServer.SimpleXMLRPCServer : alias for the SimpleXMLRPCServer class.def ls(p=""):return filter(lambda n:(p=="")or res(p,n),os.listdir(os.getcwd()))# a function lists directory entries.# INPUT: a string, p, which is a regular expression pattern.# OUTPUT: a list of directory entries matched the pattern.# DESCRIPTION:# 1. Creates a function using lambda expression that takes a pathname as its# parameter. The function returns true if the pattern is empty or the# pathname matches the pattern.# 2. Finds out what is the current working directory.# 3. Retrieves a list of directory entries of current working directory.# 4. Filters the list using the lambda function defined.if ar[2]!="client":# Running in server mode... myU,prs,srv = ("http://"+ar[3]+":"+ar[4], ar[5:],lambda x:x.serve_forever()) # A multiple assignment. # myU <- "http://"+ar[3]+":"+ar[4] : server's own URL. # prs <- ar[5:] : URL's of other servers in the network. # srv <- lambda x:x.serve_forever() : # a function to start a SimpleXMLRPCServer. # INPUT: a SimpleXMLRPCServer object, x. # OUTPUT: (none) # DESCRIPTION: # Calls the server's serve_forever() method to start handling request. def pr(x=[]): return ([(y in prs) or prs.append(y) for y in x] or 1) and prs # a function returns the server list. # INPUT: a list, x, of servers' URLs to be added to the server list. # OUTPUT: the updated server list. # DESCRIPTION: # 1. For each URL in x, checks whether it's already in the server list. # If it's not in the list, appends in onto the list. # 2. Returns the updated server list. def c(n): return ((lambda f: (f.read(), f.close()))(file(n)))[0] # a function returns content of the specified file. # INPUT: a string, n, which is a filename. # OUTPUT: the content of the file in a string. # DESCRIPTION: # 1. Creates a function using lambda expression that takes a file object, f, # as its parameter. The function reads the content of the file, then # closes it. The results of the read and close are put into a tuple, and # the tuple is returned. # 2. Creates a file object with the filename. Passes it to the lambda # function. # 3. Retrieves and returns the first item returned from the lambda function. f=lambda p,n,a:(p==pw(myU))and(((n==0)and pr(a))or((n==1)and [ls(a)])or c(a)) # a request handling function, depending on the mode, returns server list, # directory entries, or content of a file. # INPUT: a string, p, which is a hexdecimal HMAC digest. # a mode number, n. # if n is 0, a is a list of servers to be added to server list. # if n is 1, a is a pattern string. # if n is anything else, a is a filename. # OUTPUT: if n is 0, returns the server list. # if n is 1, returns directory entries match the pattern. # if n is anything else, returns content of the file. # DESCRIPTION: # 1. Verifies the password by comparing the HMAC digest received and the # one created itself. Continues only when they match. # 2. If n is 0, calls pr() to add list, a, and returns the result. # If n is 1, calls ls() to list entries match pattern a, and returns # the result enclosed in a list. # If n is any other value, retreives and return content of the file # with filename specified in a. def aug(u): return ((u==myU) and pr()) or pr(pxy(u).f(pw(u),0,pr([myU]))) # a function augments the network. # INPUT: a string, u, which is a URL. # OUTPUT: a list of URL's of servers in the network. # DESCRIPTION: # 1. If the URL, u, equals to my own URL, just returns the server list. # 2. Otherwise, creates a ServerProxy object for server u. Then calls its # request handling function f with a HMAC digest, mode 0, and server # list with myself added. # 3. Calls pr() with the result returned from server u to add them to my # own list. # 4. Returns the new list. pr() and [aug(s) for s in aug(pr()[0])] or pr([myU]) # 1. Checks the server list is not empty. # 2. Takes the first server on the list. Asks that server to augment its # server list with my URL. # 3. For each server on the returned list, asks it to add this server to its # list. (lambda sv:sv.register_function(f,"f") or srv(sv))(xs((ar[3],int(ar[4])))) # Starts request processing. # 1. Defines a function with lambda expression that takes a SimpleXMLRPCServer # object, registers request handling function, f, and starts the server. # 2. Creates a SimpleXMLRPCServer object using hostname (ar[3]) and portnum # (ar[4]). Then feeds the object to the lambda function. # Running in client mode...for url in pxy(ar[3]).f(pw(ar[3]),0,[]):# 1. Create a ServerProxy object using the serverurl (ar[3]).# 2. Calls the remote server and retrieves a server list.# 3. For each URL on the list, do the following: for fn in filter(lambda n:not n in ls(), (pxy(url).f(pw(url),1,ar[4]))[0]): # 1. Create a ServerProxy object using the URL. # 2. Calls the remote server to return a list of filenames matching the # pattern (ar[4]). # 3. For each filename doesn't exist locally, do the following: (lambda fi:fi.write(pxy(url).f(pw(url),2,fn)) or fi.close())(file(fn,"wc")) # 1. Define a lambda function that takes a file object, calls remote server # for the file content, then closes the file. # 2. Create a file object in write and binary mode with the filename. (I # think the mode "wc" should be "wb".) # 3. Passes the file object to the lambda function.
其运行方法也很容易从网上找到:
服务器:python tinyp2p.py 123456 server 127.0.0.1 12345
客户端:python tinyp2p.py 123456 client http://127.0.0.1:12345 hello.py
运行服务器,需要配置密码、ip、端口。
运行客户端,需要配置和服务器已保存的密码、ip、端口,最后一个参数是要下载的文件名(本机上测试时该文件应该在服务器源代码文件所在路径下)。
然后就是这样一段广为流传的代码却有两个问题。
1. 作为服务器可以正常运行,作为客户端不能正常运行,会报如下的错误:
File "tinyp2p.py", line 14, in ?for url in pxy(ar[3]).f(pw(ar[3]),0,[]):File "/usr/lib/python2.4/xmlrpclib.py", line 1096, in __call__return self.__send(self.__name, args)File "/usr/lib/python2.4/xmlrpclib.py", line 1383, in __requestverbose=self.__verboseFile "/usr/lib/python2.4/xmlrpclib.py", line 1147, in requestreturn self._parse_response(h.getfile(), sock)File "/usr/lib/python2.4/xmlrpclib.py", line 1286, in _parse_responsereturn u.close()File "/usr/lib/python2.4/xmlrpclib.py", line 744, in closeraise Fault(**self._stack[0])xmlrpclib.Fault: <Fault 1: 'exceptions.TypeError:coercing to Unicode:need string or buffer, list found'>
解决的办法是修改代码(不含注释)的第11行:
pr() and [aug(s) for s in aug(pr()[0])]topr() and [aug(s) for s in aug(pr()[0])] or pr([myU])
2.只能传输小于10KB的文件
传输超过10KB的文件,会报如下的错误:
Traceback (most recent call last): File "tinyp2p.py", line 22, in <module> (lambda fi:fi.write(pxy(url).f(pw(url),2,fn)) or fi.close())(file(fn,"wc")) File "tinyp2p.py", line 22, in <lambda> (lambda fi:fi.write(pxy(url).f(pw(url),2,fn)) or fi.close())(file(fn,"wc")) File "C:\Program Files (x86)\Python27\lib\xmlrpclib.py", line 1224, in __call__ return self.__send(self.__name, args) File "C:\Program Files (x86)\Python27\lib\xmlrpclib.py", line 1578, in __request verbose=self.__verbose File "C:\Program Files (x86)\Python27\lib\xmlrpclib.py", line 1264, in request return self.single_request(host, handler, request_body, verbose) File "C:\Program Files (x86)\Python27\lib\xmlrpclib.py", line 1297, in single_request return self.parse_response(response) File "C:\Program Files (x86)\Python27\lib\xmlrpclib.py", line 1467, in parse_response p.feed(data) File "C:\Program Files (x86)\Python27\lib\xmlrpclib.py", line 557, in feed self._parser.Parse(data, 0)xml.parsers.expat.ExpatError: not well-formed (invalid token): line 5, column 17
这个暂时还没找到解决方法。
- TinyP2P如何运行 How tinyp2p works!
- TinyP2P 世界最小的P2P应用
- "Karma-How It Works"Karma怎么运行
- 浏览器是如何工作的 - How Browser works
- 浏览器是如何工作的 - How Browser works(一)
- 浏览器是如何工作的 - How Browser works(二)
- 浏览器是如何工作的 - How Browser works(三)
- 浏览器是如何工作的 - How Browser works(四)
- jQuery入门:jQuery是如何工作的 How jQuery Works
- #180 – How Layout Works(WPF布局如何工作)
- How Internet EDI Works
- How E-mail Works
- How E-mail Works
- How Google Works
- How DES works
- How Google Works
- How Google Map Works
- How NAT Works
- OpenGL 动态波纹效果(着色器)
- 制作自己的Linux系统与启动光盘(2)
- mvn 创建项目
- C# 获取文件大小,创建时间,文件信息,FileInfo类的属性表
- crash 调试vmcore
- TinyP2P如何运行 How tinyp2p works!
- asp.net中form的Post和Get方法详讲
- ASP.NET MVC Tip #46 – 勿使用Delete链接,会造成安全漏洞
- 状态模式(State Pattern)
- 小心你的网站让百度蜘蛛抓取不到
- poj 1093 Formatting Text (DP)
- Android学习笔记:Activity-Spinner
- C语言中源文件和头文件的那些事
- 开源爬虫larbin分析