0% found this document useful (0 votes)
17 views27 pages

Lab Manual-Be-Dc-41

The document outlines a series of experiments focused on implementing Interprocess Communication (IPC), Remote Procedure Calls (RPC), Remote Method Invocation (RMI), and Group Communication in client-server models. Each experiment includes aims, theoretical background, code examples, observations, and conclusions regarding the successful implementation of communication mechanisms between processes. The experiments demonstrate practical applications of socket programming and RMI in facilitating reliable message exchanges in distributed systems.

Uploaded by

Sanskruti More
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
17 views27 pages

Lab Manual-Be-Dc-41

The document outlines a series of experiments focused on implementing Interprocess Communication (IPC), Remote Procedure Calls (RPC), Remote Method Invocation (RMI), and Group Communication in client-server models. Each experiment includes aims, theoretical background, code examples, observations, and conclusions regarding the successful implementation of communication mechanisms between processes. The experiments demonstrate practical applications of socket programming and RMI in facilitating reliable message exchanges in distributed systems.

Uploaded by

Sanskruti More
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 27

EXPERIMENT NO.

__1__

Aim of the Experiment :- To implement Inter process Communication.

Lab Outcome :- Develop test and debug usingMessage-Oriented Communication or


RPC/RMI based client-server programs.

Date of Performance :- _____________________

Date of Submission :- ______________________

Implementation Understanding Punctuality & Discipline Total Marks


(05) (05) (05) (15)

______________________________________

Practical Incharge
EXPERIMENT No. 1

Aim: To implement Inter process Communication.


Theory: Inter process communication (IPC) is a mechanism which allows processes to
communicate with each other and synchronize their actions. The communication between these
processes can be seen as a method of co-operation between them. Processes can communicate
with each other using these two ways:
1.​Shared Memory
2.​Message passing

Interprocess communication in a distributed environment provides both Datagram and stream


communication.
Examples Of Interprocess Communication:

1.​ N number of applications can communicate with the X server through network protocols.
2.​ Servers like Apache spawn child processes to handle requests.
3.​ Pipes are a form of IPC: grep foo file
| sort It has two functions:
1.​ Synchronization:
Exchange of data is done synchronously which means it has a single clock pulse.
2.​ Message Passing:
When processes wish to exchange information. Message passing takes several forms such
as: pipes, FIFO, Shared Memory, and Message Queues.

Messaging Passing Method:

3.​ If two processes p1 and p2 want to communicate with each other, they proceed as follow:
4.​ Establish a communication link (if a link already exists, no need to establish it again.)
5.​ Start exchanging messages using basic
primitives. We need at least two primitives:
–​send(message, destination) or send(message)
–​receive(message, host) or receive(message)
6.​ The message size can be of fixed size or of variable size. If it is of fixed size, it is easy for
the OS designer but complicated for programmers and if it is of variable size then it is easy
for programmers but complicated for the OS designer. A standard message can have two
parts: header and body.
The header part is used for storing Message type, destination id, source id, message
length and control information. The control information contains information like what
to do if it runs out of buffer space, sequence number, priority.
CODE:

Server (Receiver Process):


import socket

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)


host = 'localhost'
port = 12345
server_socket.bind((host, port))
server_socket.listen(1)
print("Server listening on port", port)

client_socket, addr = server_socket.accept()


print(f"Connected to {addr}")

message = client_socket.recv(1024).decode('utf-8')
print(f"Message from client: {message}")

client_socket.close()

Client (Sender Process):


import socket

client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)


host = 'localhost'
port = 12345
client_socket.connect((host, port))
message = "Hello, Server!"
client_socket.send(message.encode('utf-8'))

client_socket.close()

Output:

Observations andFindings:

The experiment demonstrated IPC using socket programming, where the server listened for client connections,
and the client sent a message, which the server received and displayed. TCP sockets ensured reliable
communication, but the setup allowed only one-way messaging, which could be improved by enabling
two-way communication.

Conclusion:

This experiment successfully implements Interprocess Communication (IPC) using socket programming for
reliable message passing between processes.
EXPERIMENT NO.__2__

Aim of the Experiment :- Client/server using RPC

Lab Outcome :- Develop test and debug usingMessage-Oriented Communication or RPC/RMI


based client-server programs.

Date of Performance :- _____________________

Date of Submission :- ______________________

Implementation Understanding Punctuality & Discipline Total Marks


(05) (05) (05) (15)

______________________________________

Practical Incharge
EXPERIMENT NO: 2 A

AIM : Client/server using RPC


Theory:
The client-server model is one of the most used communication paradigms in networked systems.
The server accepts the connection from the client, binds a new socket to the same local port, and
sets its remote endpoint to the client's address and port. It needs a new socket so that it can
continue to listen to the original socket for connection requests when the attention needs for the
connected client.
Creating a server program:

The EchoServer example creates a server socket and waits for a client request. When it receives a

client request, the server connects to the client and responds to it.

Following are the steps to create echo server application


Create and open a server socket.
ServerSocket serverSocket = new ServerSocket(portNumber);

The portNumber argument is the logical address through which the application communicates
over the network. It's the port on which the server is running. You must provide the port number
through which the server can listen to the client. Don't select port numbers between 0 and 1,023
because they're reserved for privileged users (that is, super user or root). Add the server socket
inside the try with- resources block.
Wait for the client request.
Socket clientSocket = serverSocket.accept();

The accept() method waits until a client starts and requests a connection on the host and port of
this server. When a connection is requested and successfully established, the accept()method
returns a new Socket object. It's bound to the same local port, and its remote address and remote
port are set to match the client's. The server can communicate with the client over this new object
and listen for client connection requests

Open an input stream and an output stream to the client.


out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
Communicate with the client.
Receive data from the client: (inputLine = in.readLine())
Send data to the client: out.println(inputLine);
●​ Close the streams and then close the socket.

Creating a client program:


The client knows the host name of the machine on which the server is running. It also knows the
port number on which the server is listening. To make a connection request, the client tries to
connect with the server on the server's machine and port. Because the client also needs to identify
itself to the server, it binds to a local port number that it will use during this connection. The
system typically assigns the port number.

Following are the various steps to create client.


Create and open a client socket.
Socket echoSocket = new Socket(hostName, portNumber);
The hostName argument is the machine where you are trying to open a connection, and
portNumber is the port on which the server is running. Don't select port numbers between 0 and
1,023 because they're reserved for privileged users (that is, super user or root).
Open an input stream and an output stream to the socket.
PrintWriter out = new PrintWriter(echoSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new
InputStreamReader(echoSocket.getInputStream()));
Read from and write to the stream according to the server's protocol.
Receive data from the server: (userInput = stdIn.readLine())

Send data to the server: out.println(userInput);


Close the streams and then close the socket.

CODE:
Server Code (RPC Server - Java)

import java.io.*;

import java.net.*;

public class RPCServer {

public static void main(String[] args) {

int port = 5000; // Server port number

try {

ServerSocket serverSocket = new ServerSocket(port);


System.out.println("Server is running on port " + port);

while (true) {

Socket clientSocket = serverSocket.accept();

System.out.println("Client connected: " + clientSocket.getInetAddress());

BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);

String request = in.readLine(); // Read request from client

if (request != null) {

System.out.println("Received request: " + request);

String response = processRequest(request);

out.println(response); // Send response back to client

clientSocket.close(); // Close client connection

} catch (IOException e) {

e.printStackTrace();

private static String processRequest(String request) {

switch (request) {

case "TIME":

return "Server Time: " + System.currentTimeMillis();

case "HELLO":

return "Hello from Server!";

case "EXIT":

return "Connection Closing...";

default:

return "Invalid Request!";


}

Client Code (RPC Client - Java)

import java.io.*;

import java.net.*;

public class RPCClient {

public static void main(String[] args) {

String serverAddress = "127.0.0.1"; // Server IP

int port = 5000; // Server Port

try {

Socket socket = new Socket(serverAddress, port);

System.out.println("Connected to server at " + serverAddress + ":" + port);

PrintWriter out = new PrintWriter(socket.getOutputStream(), true);

BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

// Sending request to server

String request = "TIME"; // Options: TIME, HELLO, EXIT

out.println(request);

// Receiving response from server

String response = in.readLine();

System.out.println("Response from Server: " + response);

socket.close(); // Close connection

} catch (IOException e) {

e.printStackTrace();

}
Output:

Observations andFindings:

In this experiment, the server successfully created a socket and listened for client requests on a specified port.
The client established a connection with the server and initiated communication through input and output
streams. Once connected, the server processed the client’s request and echoed back the received message,
demonstrating the fundamental concept of Remote Procedure Call (RPC). The interaction between the client
and server was seamless, confirming the proper implementation of the client-server model. The experiment
effectively showcased real-time message exchange and validated the working of network communication in a
distributed system.

Conclusion:

This experiment successfully implements the Client-Server model using RPC, demonstrating real-time
communication and message exchange over a network.
EXPERIMENT NO.__2B__

Aim of the Experiment :-Implement a program to illustrate the concept of Remote Method
Invocation (RMI)

Lab Outcome :- Develop test and debug usingMessage-Oriented Communication or RPC/RMI


based client-server programs.

Date of Performance :- _____________________

Date of Submission :- ______________________

Implementation Understanding Punctuality & Discipline Total Marks


(05) (05) (05) (15)

______________________________________

Practical Incharge
EXPERIMENT No. 2 B

AIM : Implement a program to illustrate the concept of Remote Method Invocation (RMI)
Problem : Design a distributed application using remote method invocation where client submit
two strings to server and returns concatenation of given string.

OBJECTIVES:
To study RMI concepts.
To know how to invoke a method running in different JVM.
To study how to write an application using RMI methodology.

THEORY/ALGORITHM:

The main objective of RMI is to provide the facility of invoking method on server. This is done by
creating a RMI Client and RMI Server. RMI Client invokes a method defined on the RMI Server.
In this article, we will learn:
RMI terminology:
Following figure shows the terminology of Remote Method Invocation.

Figure 1 : Method is invoked by client on the server using RMI

RMI is used to communicate between two running java applications on different JVM (Java
Virtual Machines). The main motive behind RMI implementation is to invoke one method running
on different JVM. The JVM Application, in which an invoked method is running out, is called
RMI Server, where as the invoking application running on the different JVM is called RMI Client.
RMI Client: It is an object that invokes remote methods on an RMI Server.
Stub: A stub is proxy that stands for RMI Server on client side and handles remote method
invocation on behalf of RMI Client.
Skeleton: It is a proxy that stands for RMI client on server side and handles remote method
invocation on RMI Server on behalf of client.
Registry Service: A Registry Service is an application that provides the facility of registration &
lookup of Remote stub.
A Registry Service provides location transparency of Remote Object to RMI Client.
Figure 2 : Role of stub and skeleton in RMI
Algorithm:
Step 1: Define Remote Interface
A remote interface specifies the methods that can be invoked remotely by a client. Clients
program communicate to remote interfaces, not to classes implementing it. To be a remote
interface, an interface must extend the Remote interface of java.rmi package.
Step 2: Implementation of remote interface
For implementation of a remote interface, a class must either extend UnicastRemoteObject or use
exportObject() method of the UnicastRemoteObject class.
Step 3: Create AddServer and host rmi service
You need to create a server application and host rmi service Adder in it. This is done using
rebind() method of java.rmi.Naming class. rebind() method take two arguments, first represent the
name of the object reference and second argument is reference to instance of Adder
Step 4: Create client application
Client application contains a java program that invokes the lookup() method of the Naming class.
This method accepts one argument, the rmi URL and returns a reference to an object of type
AddServerInterface. All remote method invocation is done on this object.

CODE:
import java.rmi.*;
import java.rmi.server.*;
import java.rmi.registry.*;

public class RMIConcat extends UnicastRemoteObject implements RMIConcatInterface {

// Constructor
protected RMIConcat() throws RemoteException {
super();
}

// Remote method implementation


public String concatenate(String str1, String str2) throws RemoteException {
return str1 + str2;
}

public static void main(String[] args) {


try {
// Start RMI registry
LocateRegistry.createRegistry(1099);
System.out.println("RMI Registry started...");

// Create and bind the remote object


RMIConcat obj = new RMIConcat();
Naming.rebind("ConcatService", obj);
System.out.println("Server is running...");

// Run the client


RMIConcatInterface stub = (RMIConcatInterface) Naming.lookup("rmi://localhost/ConcatService");
String result = stub.concatenate("Hello, ", "World!");
System.out.println("Concatenated String: " + result);

} catch (Exception e) {
System.out.println("Exception: " + e);
}
}
}

// Remote Interface
interface RMIConcatInterface extends Remote {
String concatenate(String str1, String str2) throws RemoteException;
}

Output:

Observations andFindings:

Remote Method Invocation (RMI) enables communication between Java applications running on different
JVMs by allowing a client to invoke methods on a remote server object. The experiment demonstrated how
the client looks up the remote object using the RMI registry and invokes the concatenation method, with the
server responding as expected. The use of UnicastRemoteObject allows seamless method execution over the
network, and the experiment highlighted the importance of binding the remote object properly and ensuring
the RMI registry is running before executing the client program.

Conclusion:

The experiment successfully demonstrated RMI by enabling a client to invoke a remote method for string
concatenation, proving its usefulness in distributed application
EXPERIMENT NO.__3__

Aim of the Experiment :- To implement Group Communication.

Lab Outcome :- Develop test and debug usingMessage-Oriented Communication or RPC/RMI


based client-server programs.

Date of Performance :- _____________________

Date of Submission :- ______________________

Implementation Understanding Punctuality & Discipline Total Marks


(05) (05) (05) (15)

______________________________________

Practical Incharge
EXPERIMENT No. 3

Aim: To implement Group Communication.


Objectives:
1)​ Process groups may be dynamic. New groups can be created and old
groups can be destroyed.
2)​ A process can join a group or leave one during system
operation. 3)A process can be a member of several groups at the
same time.
4)​Consequently, mechanisms are needed for managing groups and group membership.
5)​ Ordering of the messeges can be considered.
6)​ Security of the message can also be added.

Theory: Communication in consists of three or more people/ processes who share a common goal
and communicate collectively to achieve it
The key property that all groups have is that when a message is sent to the group itself, all
members of the group receive it.
The purpose of introducing groups is to allow processes to deal with collections of processes
as a single abstraction. Thus a process can send a message to a group of servers without
having to know who they are or how many there are or where they are, which may change
from one call to the next.
Types of Group:
Flat Groups versus Hierarchical Groups
1)​ Flat Groups : All the processes are equal. No one is boss and all decisions are made
collectively. The flat group is symmetrical and has no single point of failure. If one of the
processes crashes, the group simply becomes smaller, but can otherwise continue. A disadvantage
is that decision making is more complicated. For example, to decide anything,
a vote often has to be taken, incurring some delay and overhead.

2)​ Hierarchical Groups : Some kind of hierarchy exists. For example, one process is the
coordinator and all the others are workers. In this model, when a request for work is generated,
either by an external client or by one of the workers, it is sent to the coordinator. The coordinator
then decides which worker is best suited to carry it out, and forwards it there. More complex
hierarchies are also possible, of course
Figure (a) Communication in a flat group. (b) Communication in a simple hierarchical group.

Group Membership:
1)​ When group communication is present, some method is needed for creating and deleting
groups, as well as for allowing processes to join and leave groups.
2)​Member join: Either co-coordinator or by broadcasting
3)​ Member leaving : simply by sending message to group or co-coordinator removing.
4)​Leaving and joining have to be synchronous with data messages being sent.
A process has joined a group, it must receive all messages sent to that group. Similarly, as soon
as a process has left a group, it must not receive any more messages from the group, and the other
members must not receive any more messages from it.
Co-coordinator crash: Make new co-ordinator

CODE:
class Group:
def __init__(self, name):
self.name = name
self.members = set() # Set of members in the group

def add_member(self, process):


self.members.add(process)
print(f"Process {process} added to group {self.name}.")

def remove_member(self, process):


if process in self.members:
self.members.remove(process)
print(f"Process {process} removed from group {self.name}.")

def send_message(self, message):


for member in self.members:
print(f"Message to {member}: {message}")
class Process:
def __init__(self, name):
self.name = name
self.groups = set() # Set of groups the process is a member of

def join_group(self, group):


group.add_member(self.name)
self.groups.add(group)
print(f"Process {self.name} joined group {group.name}.")

def leave_group(self, group):


group.remove_member(self.name)
self.groups.remove(group)
print(f"Process {self.name} left group {group.name}.")

# Example Usage
group1 = Group("Group1")
group2 = Group("Group2")

process1 = Process("Process1")
process2 = Process("Process2")

process1.join_group(group1)
process2.join_group(group1)
process2.join_group(group2)

group1.send_message("Hello from Group1!")


group2.send_message("Hello from Group2!")

process2.leave_group(group1)
group1.send_message("Goodbye from Group1!")

Output:
Observations and Findings:
The experiment successfully demonstrates group-based interprocess communication (IPC) using
object-oriented programming in Python. The Group class manages a set of processes, allowing them to join or
leave. The Process class maintains a record of groups it belongs to. When a process joins a group, it is added
to the group's member list, enabling message broadcasting. The send_message function ensures that all
members of a group receive messages. The test execution showed that processes successfully joined multiple
groups, received messages, and were properly removed when they left a group.

Conclusion:
This experiment successfully implements group-based interprocess communication, allowing processes to
dynamically join or leave groups and enabling efficient message broadcasting to all group members.
EXPERIMENT NO.__4__

Aim of the Experiment :- To implement Christian’s clock synchronization Algorithm

Lab Outcome :- Implement techniques for clock synchronization.

Date of Performance :- _____________________

Date of Submission :- ______________________

Implementation Understanding Punctuality & Discipline Total Marks


(05) (05) (05) (15)

______________________________________

Practical Incharge
EXPERIMENT No. 4

Aim: To implement Christian’s clock synchronization Algorithm


PROBLEM: Construct a program to demonstrate the concept of clock synchronization in a
distributed environment .
OBJECTIVES:
To study clock synchronization issues in distributed environment.
THEORY/ALGORITHM:
Distributed system is a collection of computers that are interconnected via some communication
networks. Basically all the computers in a distributed system are physically separated and they
may be located apart from each other. Therefore all the process that interact with each other
need to be synchronized in the context of time to achieve some goal.
There are certain limitations of distributed systems that leave impact on the design of distributed
systems
Following are some inherent limitations :
No global clock available
No shared Memory
In distributed system, there is no common or global clock available. Since in some situations, the
programs on different computers need to coordinate their actions by exchanging messages. Due to
the unavailability of notion of a global clock there are limits on the accuracy of the output. For
that purpose temporal ordering of events is required for scheduling processes and it becomes very
difficult for a distributed system.

Christian's algorithm is a method for clock synchronization which can be used in many fields of
distributive computer science but is primarily used in low-latency intranets. Christian observed
that this simple algorithm is probabilistic, in that it only achieves synchronization if the round-trip
time (RTT) of the request is short compared to required accuracy
.

Algorithm: -

Christian's algorithm works between a process P, and a time server S connected to a source of
UTC(Coordinated Universal Time).

1.​ P requests the time from S


2.​ After receiving the request from P, S prepares a response and appends the time
T from its own clock.
3.​ P then sets its time to be T +RTT/2

This method assumes that the RTT is split equally between request and response, which may
not always be the case but is a reasonable assumption on a LAN connection.
Further accuracy can be gained by making multiple requests to S and using the response with
the shortest RTT.
Let min be the minimum time to transmit a message one-way. The earliest point at which S
could have placed the time T, was min after P sent its request. Therefore, the time at S, when
the message by P is received, is in the range (T + min) to (T + RTT - min). The width of this
range is (RTT - 2*min). This gives an accuracy of (RTT/2 - min).

Server Side:

1.​ Open a socket.


2.​ Wait for request from client
3.​ Open an input stream and output stream to socket
4.​ Process the input with processing function and reply time.
5.​ Close program
6.​ Close socket
Client side

1.​ Open a socket.


2.​ Request server for system time
3.​ While requesting save client system timeT0.
4.​ When request served note client system timeT1.
5.​ (T0.- T1)/2 Compare Server time.
6.​ Add a difference to client system.
7.​ Display result
8.​ Close stream.
9.​ Close connection.

CODE:

Server Side (Time Server)

This program listens for incoming requests from clients. When a request is received, the server sends back
its current time (UTC or server time).

import socket
import time

def start_server():
# Create a socket object
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Define the host and port for the server


host = '127.0.0.1' # Localhost
port = 12345 # Port to bind to

# Bind the server to the address


server_socket.bind((host, port))

# Start listening for incoming client connections


server_socket.listen(1)
print(f"Server listening on {host}:{port}...")

# Wait for a connection


client_socket, client_address = server_socket.accept()
print(f"Connection established with {client_address}")

# Handle communication with the client


while True:
try:
# Receive request from the client (e.g., a timestamp request)
request = client_socket.recv(1024).decode()
if not request:
break

# Get the current UTC time


server_time = time.time()

# Send back the server's time


client_socket.send(str(server_time).encode())
except Exception as e:
print(f"Error: {e}")
break

# Close the client connection


client_socket.close()
# Close the server socket
server_socket.close()

if __name__ == "__main__":
start_server()

Client Side (Time Synchronization Client)

This client sends a request to the server for the current time. It then calculates the adjusted time based on the
round-trip time and the server's response.

import socket
import time

def synchronize_clock():
# Define the server's address and port
server_host = '127.0.0.1' # Server IP
server_port = 12345 # Port of the time server

# Create a socket object


client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Connect to the server


client_socket.connect((server_host, server_port))

# Record the client time before sending the request


T0 = time.time()

# Send a request to the server (e.g., asking for the time)


client_socket.send(b"GET_TIME")

# Receive the server's time


server_time_str = client_socket.recv(1024).decode()
# Record the client time after receiving the response
T1 = time.time()

# Calculate the round-trip time (RTT)


RTT = T1 - T0

# Parse the server time


server_time = float(server_time_str)

# Adjust the client time based on the received server time


adjusted_time = server_time + RTT / 2

# Display the adjusted time


print(f"Server Time (UTC): {server_time}")
print(f"Round-Trip Time (RTT): {RTT} seconds")
print(f"Adjusted Client Time: {adjusted_time}")

# Close the client socket


client_socket.close()

if __name__ == "__main__":
synchronize_clock()

Output:
Observations and Findings:

The experiment successfully demonstrated Christian’s clock synchronization algorithm in a distributed


environment. The server provided the current UTC time upon request, while the client recorded timestamps
before and after the request to calculate the round-trip time (RTT). The client adjusted its clock using the
formula T + RTT/2, assuming equal transmission time for the request and response. The implementation
effectively synchronized the client’s time with the server’s, showcasing the importance of minimizing RTT for
higher accuracy. However, network latency variations could impact precision, which can be improved by
averaging multiple requests.

Conclusion:
This experiment successfully implements Christian’s clock synchronization algorithm, demonstrating effective
client-server time synchronization in a distributed system.

You might also like