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

1.目录结构

|__ config.ini

|__P2PClinet.py

|__P2PServer.py

|__url.txt

2.文件内容

config.ini

[SERVER_INFO]
PORT = 服务器端口号
DIRECTORY = 共享文件夹的路径
URL_FILE = url.txt

P2PClinet.py

'''
Created on 2012-7-21

author: Jeff_Yu
'''

from xmlrpclib import ServerProxy, Fault
from cmd import Cmd, PROMPT
from random import choice
from string import lower, lowercase
from P2PServer import Node, UNHANDLED
from threading import Thread
from time import sleep
import sys, ConfigParser, socket

HEAD_START = 0.1 # seconds
SECRET_LENGTH = 100


def randomString(length):
    """return the random string by given length"""
    
    chars = []
    letters = lowercase[:26]
    while length > 0:
        length -= 1
        chars.append(choice(letters))
        
    return ''.join(chars)

class Client(Cmd):
    
    prompt = '>'
    
    def __init__(self, url, dirname, urlfile):
        
        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 = ServerProxy(url)
        for line in open(urlfile):
            line = line.strip()
            self.server.hello(line)
            

    def do_fetch(self, arg):
        
        try:
            self.server.fetch(arg, self.secret)
        except Fault, f:
            if f.faultCode != UNHANDLED: raise
            print "Couldn't find the file", arg
            
    def do_exit(self,arg):
        
        print
        sys.exit()
        
    do_EOF = do_exit

class MyConfigParser:
    
    def __init__(self, urlfile):
        
        self.urlfile = urlfile
        
        try: 
            f = open(self.urlfile,"r")
        except IOError: 
            meg = "file %s is not found in the path >> %s" % (self.urlfile,os.path.abspath('.'))
            return (0,meg)

        self.config = ConfigParser.ConfigParser()       
        self.config.readfp(f)
        
        f.close()


    def getValueFromcfig(self,section,filed):

        try: 
            value = self.config.get(section,filed)
        except ConfigParser.NoOptionError: 
            meg = "%s is not found in file %s, under section %." %(filed, self.urlfile, section)
            return (0,meg)
            
        return(1,value)
        
        

def main():
    
    configfile = "config.ini"
    cfig = MyConfigParser(configfile)

    #get port
    res = cfig.getValueFromcfig("SERVER_INFO", 'PORT')
    if (res[0] == 0):
        print res[1]
        raw_input()
        sys.exit()
    else:
        port = res[1]
    
    #get directory
    res = cfig.getValueFromcfig("SERVER_INFO", 'DIRECTORY')
    if (res[0] == 0):
        print res[1]
        raw_input()
        sys.exit()
    else:
        directory = res[1]
        
    #get urlfile    
    res = cfig.getValueFromcfig("SERVER_INFO", 'URL_FILE')
    if (res[0] == 0):
        print res[1]
        raw_input()
        sys.exit()
    else:
        urlfile = res[1]
    
    url = "http://%s:%s"%(socket.gethostname(),port)
    
    print "You URL is %s, you can introduce it to your friend."%url
    
    client = Client(url, directory, urlfile)
    client.cmdloop()
    
if __name__ == '__main__': main()

P2PServer.py

'''
Created on 2012-7-21

author: Jeff_Yu
'''

from xmlrpclib import ServerProxy, Fault
from os.path import join, isfile, abspath
from SimpleXMLRPCServer import SimpleXMLRPCServer
from urlparse import urlparse
import sys


SimpleXMLRPCServer.allow_reuse_address = 1

MAX_HISTORY_LENGTH = 6

UNHANDLED = 100
ACCESS_DENIED = 200

class UnhandledQuery(Fault):
    """
    unable to handle the query
    """
    
    def __init__(self, message = "Couldn't handle the query"):
        Fault.__init__(self, UNHANDLED, message)
        

class AccessDenied(Fault):
    """
    Access denied
    """
    def __init__(self, message = "Access denied"):
        Fault.__init__(self, ACCESS_DENIED, message)


def inside(dir, name):
    """
    check whether can find file in the dir
    """
    dir = abspath(dir)
    name = abspath(name)
    return name.startswith(join(dir,''))


def getPort(url):
    """get port from URL"""
    
    name = urlparse(url)[1]
    parts = name.split(':')
    return int(parts[-1])


class Node:
    """P2P network node"""
    
    def __init__(self, url, dirname, secret):
        self.url = url
        self.dirname = dirname
        self.secret = secret
        self.known = set()
        
    def query(self, query, history=[]):
        """ query the file"""
        
        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):
        """introduce self"""
        
        self.known.add(other)
        return 0
    
    def fetch(self, query, secret):
        """make the node find file and download"""
        
        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):
        """start server"""
        
        s = SimpleXMLRPCServer(("", getPort(self.url)), logRequests=True, allow_none=True)
        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):
        """used to query other known 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, directory, secret)
    n._start()
    
if __name__ == '__main__': main()

url.txt

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

 

 

 使用方法截图稍后发出。。。

 

你可能感兴趣的:(python,python,p2p,文件共享,XML-RPC,使用XML-RPC进行文件共享)