How to resolve the algorithm Distributed programming step by step in the Python programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Distributed programming step by step in the Python programming language

Table of Contents

Problem Statement

Write two programs (or one program with two modes) which run on networked computers, and send some messages between them. The protocol used may be language-specific or not, and should be suitable for general distributed programming; that is, the protocol should be generic (not designed just for the particular example application), readily capable of handling the independent communications of many different components of a single application, and the transferring of arbitrary data structures natural for the language. This task is intended to demonstrate high-level communication facilities beyond just creating sockets.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Distributed programming step by step in the Python programming language

Server Side:

1. XML-RPC Server:

  • Uses SimpleXMLRPCServer to create a server that handles XML-RPC requests.
  • Registers a class instance (MyHandlerInstance) and a function (foo_function) as handlers.

2. HTTP Server:

  • Uses BaseHTTPServer to create a simple HTTP server.
  • Handles GET requests by sending a basic HTML response.

3. RPC Server (Pickle Protocol):

  • Uses SocketServer to create a TCP server for handling RPC requests.
  • Uses Pickle for serializing and deserializing data.
  • Registers an object instance (MyHandlerInstance) as the object to proxy.

4. Pyro Server:

  • Uses Pyro to create a distributed object server.
  • Registers two object instances (StringInstance and MathInstance) as services.

5. Spread Server:

  • Uses Spread to create a distributed messaging system.
  • Connects to a Spread daemon and joins a chat room called "test".

Client Side:

1. XML-RPC Client:

  • Uses xmlrpclib to create a client that can send XML-RPC requests to the server.
  • Calls methods on the server and displays the results.

2. HTTP Client:

  • Uses httplib to send a GET request to the HTTP server.
  • Receives and displays the server's response.

3. RPC Client (Pickle Protocol):

  • Uses Pickle to serialize and deserialize data.
  • Connects to the RPC server and calls methods remotely.

4. Pyro Client:

  • Uses Pyro to get proxies for the services registered on the server.
  • Calls methods on the proxies, which are transparently forwarded to the server.

5. Spread Client:

  • Uses Spread to connect to a Spread daemon and join a chat room.
  • Continuously receives messages from the chat room and displays them.

6. Spread Sender:

  • Uses Spread to connect to a Spread daemon and join a chat room.
  • Sends a message to all other participants in the chat room.

Source code in the python programming language

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import SimpleXMLRPCServer

class MyHandlerInstance:
    def echo(self, data):
        '''Method for returning data got from client'''
        return 'Server responded: %s' % data

    def div(self, num1, num2):
        '''Method for divide 2 numbers'''
        return num1/num2

def foo_function():
    '''A function (not an instance method)'''
    return True

HOST = "localhost"
PORT = 8000

server = SimpleXMLRPCServer.SimpleXMLRPCServer((HOST, PORT))

# register built-in system.* functions.
server.register_introspection_functions()

# register our instance
server.register_instance(MyHandlerInstance())

# register our function as well
server.register_function(foo_function)

try:
    # serve forever
    server.serve_forever()
except KeyboardInterrupt:
    print 'Exiting...'
    server.server_close()


#!/usr/bin/env python
# -*- coding: utf-8 -*-

import xmlrpclib

HOST = "localhost"
PORT = 8000

rpc = xmlrpclib.ServerProxy("http://%s:%d" % (HOST, PORT))

# print what functions does server support 
print 'Server supports these functions:',
print ' '.join(rpc.system.listMethods())

# echo something
rpc.echo("We sent this data to server")

# div numbers
print 'Server says: 8 / 4 is: %d' % rpc.div(8, 4)

# control if foo_function returns True
if rpc.foo_function():
    print 'Server says: foo_function returned True'


#!/usr/bin/python
# -*- coding: utf-8 -*-

import BaseHTTPServer

HOST = "localhost"
PORT = 8000

# we just want to write own class, we replace do_GET method. This could be extended, I just added basics
# see; http://docs.python.org/lib/module-BaseHTTPServer.html
class MyHTTPHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    def do_GET(self):
        # send 200 (OK) message
        self.send_response(200)
        # send header
        self.send_header("Content-type", "text/html")
        self.end_headers()

        # send context
        self.wfile.write("<html><head><title>Our Web Title</title></head>")
        self.wfile.write("<body><p>This is our body. You wanted to visit <b>%s</b> page</p></body>" % self.path)
        self.wfile.write("</html>")

if __name__ == '__main__':
    server = BaseHTTPServer.HTTPServer((HOST, PORT), MyHTTPHandler)
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        print 'Exiting...'
        server.server_close()


#!/usr/bin/python
# -*- coding: utf-8 -*-

import httplib

HOST = "localhost"
PORT = 8000

conn = httplib.HTTPConnection(HOST, PORT)
conn.request("GET", "/somefile")

response = conn.getresponse()
print 'Server Status: %d' % response.status

print 'Server Message: %s' % response.read()


#!/usr/bin/python
# -*- coding: utf-8 -*-
 
import SocketServer
import pickle
 
HOST = "localhost"
PORT = 8000

class RPCServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    # The object_to_proxy member should be set to the object we want
    # methods called on. Unfortunately, we can't do this in the constructor
    # because the constructor should not be overridden in TCPServer...

    daemon_threads = True

class RPCHandler(SocketServer.StreamRequestHandler):
    def handle(self):
        in_channel = pickle.Unpickler(self.rfile)
        out_channel = pickle.Pickler(self.wfile, protocol=2)
        while True:
            try:
                name, args, kwargs = in_channel.load()
                print 'got %s %s %s' % (name, args, kwargs)
            except EOFError:
                # EOF means we're done with this request.
                # Catching this exception to detect EOF is a bit hackish,
                # but will work for a quick demo like this
                break
            try:
                method = getattr(self.server.object_to_proxy, name)
                result = method(*args, **kwargs)
            except Exception, e:
                out_channel.dump(('Error',e))
            else:
                out_channel.dump(('OK',result))

class MyHandlerInstance(object):
    def echo(self, data):
        '''Method for returning data got from client'''
        return 'Server responded: %s' % data
 
    def div(self, dividend, divisor):
        '''Method to divide 2 numbers'''
        return dividend/divisor
 
    def is_computer_on(self):
        return True
 
if __name__ == '__main__':
    rpcserver = RPCServer((HOST, PORT), RPCHandler)
    rpcserver.object_to_proxy = MyHandlerInstance()
    try:
        rpcserver.serve_forever()
    except KeyboardInterrupt:
        print 'Exiting...'
        rpcserver.server_close()


#!/usr/bin/python
# -*- coding: utf-8 -*-
 
import socket
import pickle
 
HOST = "localhost"
PORT = 8000

class RPCClient(object):
    def __init__(self, host, port):
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.connect((host, port))
        self.rfile = self.socket.makefile('rb')
        self.wfile = self.socket.makefile('wb')
        self.in_channel = pickle.Unpickler(self.rfile)
        self.out_channel = pickle.Pickler(self.wfile, protocol=2)

    def _close(self):
        self.socket.close()
        self.rfile.close()
        self.wfile.close()

    # Make calling remote methods easy by overriding attribute access.
    # Accessing any attribute on our instances will give a proxy method that
    # calls the method with the same name on the remote machine.
    def __getattr__(self, name):
        def proxy(*args, **kwargs):
            self.out_channel.dump((name, args, kwargs))
            self.wfile.flush() # to make sure the server won't wait forever
            status, result = self.in_channel.load()
            if status == 'OK':
                return result
            else:
                raise result

        return proxy
 
if __name__ == '__main__':
    # connect to server and send data
    rpcclient = RPCClient(HOST, PORT)

    print 'Testing the echo() method:'
    print rpcclient.echo('Hello world!')
    print
    print 'Calculating 42/2 on the remote machine:'
    print rpcclient.div(42, 2)
    print
    print 'is_computer_on on the remote machine returns:'
    print rpcclient.is_computer_on()
    print
    print 'Testing keyword args:'
    print '42/2 is:', rpcclient.div(divisor=2, dividend=42)
    rpcclient._close()
    del rpcclient


#!/usr/bin/python
# -*- coding: utf-8 -*-

import Pyro.core
import Pyro.naming

# create instance that will return upper case
class StringInstance(Pyro.core.ObjBase):
    def makeUpper(self, data):
        return data.upper()

class MathInstance(Pyro.core.ObjBase):
    def div(self, num1, num2):
        return num1/num2

if __name__ == '__main__':
    server = Pyro.core.Daemon()
    name_server = Pyro.naming.NameServerLocator().getNS()
    server.useNameServer(name_server)
    server.connect(StringInstance(), 'string')
    server.connect(MathInstance(), 'math')
    try:
        server.requestLoop()
    except KeyboardInterrupt:
        print 'Exiting...'
        server.shutdown()


#!/usr/bin/python
# -*- coding: utf-8 -*-

import Pyro.core

DATA = "my name is eren"
NUM1 = 10
NUM2 = 5

string = Pyro.core.getProxyForURI("PYRONAME://string")
math = Pyro.core.getProxyForURI("PYRONAME://math")

print 'We sent: %s' % DATA
print 'Server responded: %s\n' % string.makeUpper(DATA)

print 'We sent two numbers to divide: %d and %d' % (NUM1, NUM2)
print 'Server responded the result: %s' % math.div(NUM1, NUM2)


#!/usr/bin/python
# -*- coding: utf-8 -*-

import spread

PORT = '4803'

# connect spread daemon
conn = spread.connect(PORT)
# join the room
conn.join('test')

print 'Waiting for messages... If you want to stop this script, please stop spread daemon'
while True:
    recv = conn.receive()
    if hasattr(recv, 'sender') and hasattr(recv, 'message'):
        print 'Sender: %s' % recv.sender
        print 'Message: %s' % recv.message


#!/usr/bin/python
# -*- coding: utf-8 -*-

import spread

PORT = '4803'

conn = spread.connect(PORT)
conn.join('test')

conn.multicast(spread.RELIABLE_MESS, 'test', 'hello, this is message sent from python')
conn.disconnect()


  

You may also check:How to resolve the algorithm Equal prime and composite sums step by step in the jq programming language
You may also check:How to resolve the algorithm Doubly-linked list/Definition step by step in the Icon and Unicon programming language
You may also check:How to resolve the algorithm 99 bottles of beer step by step in the Comal programming language
You may also check:How to resolve the algorithm Pascal's triangle step by step in the TI-83 BASIC programming language
You may also check:How to resolve the algorithm Inverted syntax step by step in the Wortel programming language