Use of RPC Python instance xml-rpc for remote file sharing under Linux

Source: Internet
Author: User
Tags node server

This is a good exercise, using Python to develop peer-to-peer programs, perhaps through this we can make a peer download tool, similar to thunder. XML-RPC is a remote procedure call (remotely procedure CALL,RPC) Distributed computing protocol that encapsulates the calling function via XML and uses the HTTP protocol as the delivery mechanism [excerpt from wikipedia]

1. Make a small attempt first: first enter the command line, enter the Vim pythonserver.py, and then enter the code:

 from Import  = Simplexmlrpcserver (("", 4242))  # defaults to native def  twice (x): return x*# add feature to Server # start Server

2. Enter Python to open the shell interaction command line

 from Import  = serverproxy ('http://localhost:4242') s.twice (#  Call the remote method via Serverproxy,

3. Start file sharing complete code:
3.1 Server-side server.py

#Coding=utf-8 fromXmlrpclibImportServerproxy,fault fromOs.pathImportJoin, Abspath,isfile fromSimplexmlrpcserverImportSimplexmlrpcserver fromUrlparseImportUrlparseImportsyssimplexmlrpcserver.allow_reuse_address= 1Max_history_length= 6Unhandled= 100access_denied= 200classunhandledquery (Fault):" "That ' s show can ' t handle the query exception" "    def __init__(self,message="couldn ' t handle the query"): Fault.__init__(self, unhandled, message)classAccessDenied (Fault):" "When user try to access the Forbiden resources raise exception" "    def __init__(Self, message="Access denied"): Fault.__init__(self, access_denied, message)definside (dir,name):" "Check the dir that user defined is contain the filename the user given" "dir=Abspath (dir) name=abspath (name)returnName.startswith (dir,"'))defgetport (URL):" "get the port num from the URL" "name= Urlparse (URL) [1] Parts= Name.split (':')    returnInt (parts[-1])classNode:def __init__(self, url, dirname, secret): Self.url=URL Self.dirname=dirname Self.secret=Secret Self.known=set ()defQuery (self, query, history = []):        Try:            returnself._handle (query)exceptunhandledquery:history= history +[Self.url]ifLen (History) > Max_history_length:Raise            returnself._broadcast (query,history)defHello (self,other): Self.known.add (Other)return0deffetch (self, Query, secret):ifSecret! = Self.secret:Raiseresult=self.query (query) F= Open (Join (self.dirname, query),'W') f.write (Result) f.close ()return0def_start (self): s= 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  notIsfile (name):RaiseUnhandledqueryif  notInside (dir,name):RaiseAccessDeniedreturnopen (name). Read ()def_broadcast (self, Query, history): forOtherinchself.known.copy ():ifOtherinchHistoryContinue            Try: S=Serverproxy (Other)returns.query (query, history)exceptFault, F:ifF.faultcode = = Unhandled:Pass                Else: Self.known.remove (Other)except: Self.known.remove (Other)RaiseUnhandledquerydefmain (): URL, directory, secret= Sys.argv[1:] n=Node (Url,directory,secret) N._start ()if __name__=='__main__': Main ()

Let's start with a few constants above: Simplexmlrpcserver.allow_reuse_address says that the ports it occupies can be reused, that is, if you force the node server to shut down and restart again, there will be no port usage.

Max_history_length = 6 This is the maximum length of the node, because it cannot allow the node to search indefinitely.

Unhandled = Access_denied = 200 The two are return codes.

Then take a look at the specific flow of node nodes. The process of this section of code this way, first, start the server for remote invocation, the interface called is the node class. There are three methods in the node class for remote invocation, one for Hello, one for fetch and one for query. Hello this method is to add the neighboring node information to the current node. Fetch is the method used to get the data, and query is used to interact between nodes.

In the Fetch method, first determine if the password is correct, and then find the data by calling your own Query method. Let's look at the query method, which first calls the private method _handle local lookup, if not found, then in all known nodes through the _broadcast interface to send the broadcast, here to pay attention to Histroy, each broadcast will pass the history of this parameter, This parameter has two functions: one is to prevent broadcasts from being sent to a repeating node, and the other is to limit the length of all currently linked nodes.

After understanding the underlying functionality of a node server, look at the control class code that manages the server.

3.2 Client Code client.py

#Coding=utf-8 fromXmlrpclibImportServerproxy, Fault fromCmdImportCMD fromRandomImportChoice fromStringImportlowercase fromServerImportNode,unhandled#introducing the previous server fromThreadingImportThread fromTimeImportSleepImportSyshead_start= 0.1Secret_length= 100defrandomstring (length): Chars=[] Letters= lowercase[:26]     whileLength >0:length-= 1chars.append (choice (Letters))return "'. Join (chars)classClient (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) forLineinchOpen (urlfile): Line=Line.strip () Self.server.hello (line)defDo_fetch (Self, arg):Try: Self.server.fetch (Arg,self.secret)exceptfault,f:ifF.faultcode! = Unhandled:Raise            Print "couldn ' t find the file", ArgdefDo_exit (self,arg):Printsys.exit () Do_eor=Do_exitdefMain (): urlfile, directory, URL= Sys.argv[1:] Client=Client (URL, directory, urlfile) Client.cmdloop ()if __name__=='__main__': Main ()

To analyze this code, the previous parameters are not read, very good understanding, at first there is a random generation of password function, what to do with it? It is mainly used to prevent other people from illegally invoking node server controlled by this control. We don't have to remember the password because we have the legal right to use the client. Oh.

The overall function of this code is to provide you with a visual command-line interface, by inheriting the Cmd class, to parse the command you entered, such as when the program runs, a command prompt appears, you enter a fetch, then it will be called into the Do_fetch method, and the parameters passed in. Do_fetch This method is used to get resources by invoking the Fetch method in node server. Another do_exit is well understood, is to accept the exit command to exit the program.

In the initialization of the program, there is a point to note that it will read your urlfile parameter passed the data in the file, which is placed in the node URL address. After reading, the program will add these addresses to neighboring nodes for later access. However, the program is still a bit imperfect in the process of running, if you modify the URL configuration of the file, he will not read your newly added node URL. But this modification is simple, put the code to get the URL into the Do_fetch.

There is still work to be done before running the program. First you need to set up two folders, a and C,c folder inside create a file, B.txt, in A and C in the same folder to establish UrlsA.txt and urlsC.txt files. Inside the UrlsA.txt write: http://localhost:4243, then open two command lines,

First input:

Enter, is not out of the prompt. Enter the fetch B.txt carriage return and see the hint couldn ' t find the file B.txt. 、

Then, on the second command line, enter

Python client.py urlsC.txt C http://localhost:4243

Enter. Also input fetch B.txt Enter, is not unresponsive. Indicates that the file exists. After the first command line to enter the fetch B.txt again to see, whether or not to find the file, if you have the code according to my above suggestions have been modified, there will be no error, if not modified, at this time you need to put the input exit exit program, restart again, and then in the fetch B.txt, then go to the a folder to see if you can download the B.txt to your folder.

PS: The above program can only transfer text files, large files or other format files can not be transferred, just studied, using xmlrpclib this library binary function can be, the use of Access as follows: first introduced Xmlrpclib,import Xmlrpclib The last code returned in the _handle method of the server class returns to open (name). Read () is modified to return xmlrpclib. Binary (open (name, ' RB '). Read ()) and modify F.write (result) in the Fetch method to F.write (Result.data) The other way to write the file in front of this sentence is to change to WB.

"Go from" Python project Exercise VIII: Using XML-RPC for remote file sharing Thank you landlord!

Reference:

1. python zeromq RPC intro

2. talk about what Python does with RPC for distributed system calls.

Use of RPC Python instance xml-rpc for remote file sharing under Linux

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.