Python 使用XML-RPC进行文件共享


1.目录结构

|__ config.ini

|__P2PClinet.py

|__P2PServer.py

|__url.txt

2.文件内容

config.ini

1
[SERVER_INFO]
2
PORT = 服务器端口号
3
DIRECTORY = 共享文件夹的路径
4
URL_FILE = url.txt
P2PClinet.py
001
'''
002
Created on 2012-7-21
003
 
004
author: Jeff_Yu
005
'''
006
 
007
from xmlrpclib import ServerProxy, Fault
008
from cmd import Cmd, PROMPT
009
from random import choice
010
from string import lower, lowercase
011
from P2PServer import Node, UNHANDLED
012
from threading import Thread
013
from time import sleep
014
import sys, ConfigParser, socket
015
 
016
HEAD_START = 0.1 # seconds
017
SECRET_LENGTH = 100
018
 
019
 
020
def randomString(length):
021
    """return the random string by given length"""
022
    
023
    chars = []
024
    letters = lowercase[:26]
025
    while length > 0:
026
        length -= 1
027
        chars.append(choice(letters))
028
        
029
    return ''.join(chars)
030
 
031
class Client(Cmd):
032
    
033
    prompt = '>'
034
    
035
    def __init__(self, url, dirname, urlfile):
036
        
037
        Cmd.__init__(self)
038
        self.secret = randomString(SECRET_LENGTH)
039
        n = Node(url, dirname, self.secret)
040
        t = Thread(target=n._start)
041
        t.setDaemon(1)
042
        t.start()
043
        sleep(HEAD_START)
044
        self.server = ServerProxy(url)
045
        for line in open(urlfile):
046
            line = line.strip()
047
            self.server.hello(line)
048
            
049
 
050
    def do_fetch(self, arg):
051
        
052
        try:
053
            self.server.fetch(arg, self.secret)
054
        except Fault, f:
055
            if f.faultCode != UNHANDLED: raise
056
            print "Couldn't find the file", arg
057
            
058
    def do_exit(self,arg):
059
        
060
        print
061
        sys.exit()
062
        
063
    do_EOF = do_exit
064
 
065
class MyConfigParser:
066
    
067
    def __init__(self, urlfile):
068
        
069
        self.urlfile = urlfile
070
        
071
        try:
072
            f = open(self.urlfile,"r")
073
        except IOError:
074
            meg = "file %s is not found in the path >> %s" % (self.urlfile,os.path.abspath('.'))
075
            return (0,meg)
076
 
077
        self.config = ConfigParser.ConfigParser()     
078
        self.config.readfp(f)
079
        
080
        f.close()
081
 
082
 
083
    def getValueFromcfig(self,section,filed):
084
 
085
        try:
086
            value = self.config.get(section,filed)
087
        except ConfigParser.NoOptionError:
088
            meg = "%s is not found in file %s, under section %." %(filed, self.urlfile, section)
089
            return (0,meg)
090
            
091
        return(1,value)
092
        
093
        
094
 
095
def main():
096
    
097
    configfile = "config.ini"
098
    cfig = MyConfigParser(configfile)
099
 
100
    #get port
101
    res = cfig.getValueFromcfig("SERVER_INFO", 'PORT')
102
    if (res[0] == 0):
103
        print res[1]
104
        raw_input()
105
        sys.exit()
106
    else:
107
        port = res[1]
108
    
109
    #get directory
110
    res = cfig.getValueFromcfig("SERVER_INFO", 'DIRECTORY')
111
    if (res[0] == 0):
112
        print res[1]
113
        raw_input()
114
        sys.exit()
115
    else:
116
        directory = res[1]
117
        
118
    #get urlfile  
119
    res = cfig.getValueFromcfig("SERVER_INFO", 'URL_FILE')
120
    if (res[0] == 0):
121
        print res[1]
122
        raw_input()
123
        sys.exit()
124
    else:
125
        urlfile = res[1]
126
    
127
    url = "http://%s:%s"%(socket.gethostname(),port)
128
    
129
    print "You URL is %s, you can introduce it to your friend."%url
130
    
131
    client = Client(url, directory, urlfile)
132
    client.cmdloop()
133
    
134
if __name__ == '__main__': main()
P2PServer.py

001
'''
002
Created on 2012-7-21
003
 
004
author: Jeff_Yu
005
'''
006
 
007
from xmlrpclib import ServerProxy, Fault
008
from os.path import join, isfile, abspath
009
from SimpleXMLRPCServer import SimpleXMLRPCServer
010
from urlparse import urlparse
011
import sys
012
 
013
 
014
SimpleXMLRPCServer.allow_reuse_address = 1
015
 
016
MAX_HISTORY_LENGTH = 6
017
 
018
UNHANDLED = 100
019
ACCESS_DENIED = 200
020
 
021
class UnhandledQuery(Fault):
022
    """
023
    unable to handle the query
024
    """
025
    
026
    def __init__(self, message = "Couldn't handle the query"):
027
        Fault.__init__(self, UNHANDLED, message)
028
        
029
 
030
class AccessDenied(Fault):
031
    """
032
    Access denied
033
    """
034
    def __init__(self, message = "Access denied"):
035
        Fault.__init__(self, ACCESS_DENIED, message)
036
 
037
 
038
def inside(dir, name):
039
    """
040
    check whether can find file in the dir
041
    """
042
    dir = abspath(dir)
043
    name = abspath(name)
044
    return name.startswith(join(dir,''))
045
 
046
 
047
def getPort(url):
048
    """get port from URL"""
049
    
050
    name = urlparse(url)[1]
051
    parts = name.split(':')
052
    return int(parts[-1])
053
 
054
 
055
class Node:
056
    """P2P network node"""
057
    
058
    def __init__(self, url, dirname, secret):
059
        self.url = url
060
        self.dirname = dirname
061
        self.secret = secret
062
        self.known = set()
063
        
064
    def query(self, query, history=[]):
065
        """ query the file"""
066
        
067
        try:
068
            return self._handle(query)
069
        except UnhandledQuery:
070
            history = history + [self.url]
071
            if len(history) >= MAX_HISTORY_LENGTH: raise
072
            return self._broadcast(query, history)
073
        
074
    def hello(self, other):
075
        """introduce self"""
076
        
077
        self.known.add(other)
078
        return 0
079
    
080
    def fetch(self, query, secret):
081
        """make the node find file and download"""
082
        
083
        if secret != self.secret: raise AccessDenied
084
        result = self.query(query)
085
        f = open(join(self.dirname, query),'w')
086
        f.write(result)
087
        f.close()
088
        return 0
089
 
090
        
091
    def _start(self):
092
        """start server"""
093
        
094
        s = SimpleXMLRPCServer(("", getPort(self.url)), logRequests=True, allow_none=True)
095
        s.register_instance(self)
096
        s.serve_forever()
097
        
098
    def _handle(self, query):
099
        
100
        dir = self.dirname
101
        name = join(dir, query)
102
        if not isfile(name): raise UnhandledQuery
103
        if not inside(dir, name): raise AccessDenied
104
        return open(name).read()
105
    
106
    def _broadcast(self, query, history):
107
        """used to query other known Node"""
108
        
109
        for other in self.known.copy():
110
            if other in history:continue
111
            
112
            try:
113
                s = ServerProxy(other)
114
                return s.query(query, history)
115
               
116
            except Fault, f:
117
                if f.faultCode == UNHANDLED: pass
118
                else: self.known.remove(other)
119
            except:
120
                self.known.remove(other)
121
        
122
        raise UnhandledQuery
123
    
124
def main():
125
    url, directory, secret = sys.argv[1:]
126
    n = Node(url, directory, secret)
127
    n._start()
128
      www.2cto.com
129
if __name__ == '__main__': main()
url.txt

1
http://机器名称1:端口1
2
http://机器名称2:端口2
3
http://机器名称3:端口3
 作者:JeffYu

相关内容

    暂无相关文章

评论关闭