04.08.2014 Views

o_18ufhmfmq19t513t3lgmn5l1qa8a.pdf

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

CHAPTER 27 ■ PROJECT 8: FILE SHARING WITH XML-RPC 505<br />

If history isn’t too long, the next step is to broadcast the query to all known peers—which<br />

is done with the _broadcast method. The _broadcast method isn’t very complicated (see the<br />

listing for full source code). It iterates over a copy of self.known. If a peer is found in history,<br />

the loop continues to the next peer (using the continue statement). Otherwise, a ServerProxy is<br />

constructed, and the query method is called on it. If the query succeeds, its return value is used<br />

as the return value from _broadcast. Exceptions may occur, due to network problems, a faulty<br />

URL, or the fact that the peer doesn’t support the query method. If such an exception occurs,<br />

the peer’s URL is removed from self.known (in the except clause of the try statement enclosing<br />

the query). Finally, if control reaches the end of the function (nothing has been returned yet),<br />

FAIL is returned, along with an empty string.<br />

■Note You shouldn’t simply iterate over self.known because the set may be modified during the iteration.<br />

Using a copy is safer.<br />

The _start method creates a SimpleXMLRPCServer (using the little utility function getPort,<br />

which extracts the port number from a URL), with logRequests set to false (you don’t want to<br />

keep a log). It then registers self with register_instance and calls the server’s serve_forever<br />

method.<br />

Finally, the main method of the module extracts a URL, a directory, and a secret (password)<br />

from the command line, creates a Node, and calls its _start method.<br />

For the full code of the prototype, see Listing 27-1.<br />

Listing 27-1. A Simple Node Implementation (simple_node.py)<br />

from xmlrpclib import ServerProxy<br />

from os.path import join, isfile<br />

from SimpleXMLRPCServer import SimpleXMLRPCServer<br />

from urlparse import urlparse<br />

import sys<br />

MAX_HISTORY_LENGTH = 6<br />

OK = 1<br />

FAIL = 2<br />

EMPTY = ''<br />

def getPort(url):<br />

'Extracts the port from a URL'<br />

name = urlparse(url)[1]<br />

parts = name.split(':')<br />

return int(parts[-1])

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!