Distributed System
Distributed System
Lab Manual
Distributed System Lab
Index
Page |2
Lab Manual
Distributed System Lab
EXPERIMENT NO: 1
This relation only goes one way: if one event comes before another, then that event's
logical clock comes before the other's. Using only a simple Lamport clock, only a
partial causal ordering can be inferred from the clock. For example, if you know that
C(a) < C(b), then you do not know that a \rightarrow b.
However, via the contrapositive, it's true that C(a) \nless C(b) implies a \nrightarrow
b. So, for example, if C(a) \geq C(b) then a cannot have occurred before b.
Another way of putting this is that C(a) < C(b) means that a may have happened
before or at the same time as b, but a did not happen after b.
Code:
#include<stdio.h>
#include<conio.h>
int max1(int a, int b) //to find the maximum timestamp between two
events
{
if (a>b)
return a;
else
return b;
}
int main()
{
int i,j,k,p1[20],p2[20],e1,e2,dep[20][20];
printf("enter the events : ");
scanf("%d %d",&e1,&e2);
for(i=0;i<e1;i++)
p1[i]=i+1;
for(i=0;i<e2;i++)
p2[i]=i+1;
printf("enter the dependency matrix:\n");
printf("\t enter 1 if e1->e2 \n\t enter -1, if e2->e1 \n\t else enter
0 \n\n");
for(i=0;i<e2;i++)
printf("\te2%d",i+1);
for(i=0;i<e1;i++)
{
printf("\n e1%d \t",i+1);
Page |3
Lab Manual
Distributed System Lab
for(j=0;j<e2;j++)
scanf("%d",&dep[i][j]);
}for(i=0;i<e1;i++)
{
for(j=0;j<e2;j++)
{
if(dep[i][j]==1) //change the timestamp if dependency
exist
{ p2[j]=max1(p2[j],p1[i]+1);
for(k=j;k<e2;k++)
p2[k+1]=p2[k]+1;
}
if(dep[i][j]==-1) //change the timestamp if dependency
exist
{
p1[i]=max1(p1[i],p2[j]+1);
for(k=i;k<e1;k++)
p2[k+1]=p1[k]+1;
} } }
printf("P1 : "); //to print the outcome of Lamport Logical Clock
for(i=0;i<e1;i++)
{
printf("%d",p1[i]);
}
printf("\n P2 : ");
for(j=0;j<e2;j++)
printf("%d",p2[j]);
getch();
return 0 ; }
Page |4
Lab Manual
Distributed System Lab
Q4. A client's clock reads 3:20:00. The server's clock reads 3:10:00 when they
synchronize. Assume message delays are negligible. What is the time at the
client after synchronization?
Page |5
Lab Manual
Distributed System Lab
EXPERIMENT NO: 2
Algorithm:
A vector clock is an algorithm for generating a partial ordering of events in a
distributed system and detecting causality violations. Just as in Lamport timestamps,
interprocess messages contain the state of the sending process's logical clock. A vector
clock of a system of N processes is an array/vector of N logical clocks, one clock per
process; a local "smallest possible values" copy of the global clock-array is kept in
each process, with the following rules for clock updates:
Initially all clocks are zero.
Each time a process experiences an internal event, it increments its own logical
clock in the vector by one.
Each time a process prepares to send a message, it sends its entire vector along
with the message being sent.
Each time a process receives a message, it increments its own logical clock in the
vector by one and updates each element in its vector by taking the maximum of
the value in its own vector clock and the value in the vector in the received
message (for every element).
Code:
#include<stdio.h>
void main()
{
int max,i,j,r,e1[2],e2[2],e3[2],e4[2],k;
printf("sending node is e1\n");
printf("enter the receiving node no as either 3 or 4\n");
scanf("%d",&r);
printf("enter the value of k");
scanf("%d",&k);
for(i=0;i<2;i++)
{
e1[i]=0;
e2[i]=0;
e3[i]=0;
e4[i]=0;
}
e1[0]=e1[0]+k;
e2[0]=e1[0]+k;
e3[1]=e3[1]+k;
e4[1]=e3[1]+k;
if(r==3)
{
if(e1[0]>e3[0])
e3[0]=e1[0];
if(e1[1]>e3[1])
e3[1]=e1[1];
if(e4[0]<e3[0])
e4[0]=e3[0];
Page |6
Lab Manual
Distributed System Lab
if(e4[1]<e3[1])
e4[1]=e3[1];
}
if(r==4)
{
if(e1[0]>e4[0])
e4[0]=e1[0];
if(e1[1]>e4[1])
e4[1]=e1[1];
}
Q1. What is the limitation of Lamport Clock that vector clock overcomes?
Q2. What are the implantation rules for Vector clock?
Q3. Enlist the name of algorithms/application that uses Vector clock
Q4. In this scenario, three nodes, named A, B, and C are working on a job for a
user.
The sequence of events is given:
e1 ) C sends sync request to F
e2 ) B receives sync request from C
e3 ) C sends sync request to A
e4 ) B sends sync request to A
e5 ) A receives sync request from C
e6 ) A sends sync acknowledgement t o C
e7 ) C receives job from user
e8 ) C receives sync acknowledgement from A
e9 ) B send s sync acknowledgement t o C
e10 ) C sends work to A
e11 ) A receives work from C and begins processing
Using this sequence of events:
Page |7
Lab Manual
Distributed System Lab
(a) Write out the Lamport Clock representation of each timestep, using the
notation L([event]) = [Lamport Timestep]. For example, L(e1) = 1.
(b) Write out the vector time representation of each timestep
Page |8
Lab Manual
Distributed System Lab
EXPERIMENT NO: 3
Objective: Write a program to execute the concept distributed mutual exclusion for
non-token based algorithm
Algorithm:
Lamport’s algorithm
Nodal properties
Every process maintains a queue of pending requests for entering critical section
order. The queues are ordered by virtual time stamps derived from Lamport
timestamps.
Algorithm
Requesting process
Enters its request in its own queue (ordered by time stamps)
Sends a request to every node.
Wait for replies from all other nodes.
If own request is at the head of its queue and all replies have been received, enter
critical section.
Upon exiting the critical section, remove its request from the queue and send a release
message to every process.
Other processes
After receiving a request, enter the request in its own request queue (ordered by time
stamps) and reply with a time stamp.
After receiving release message, remove the corresponding request from its own
request queue.
If own request is at the head of its queue and all replies have been received, enter
critical section
Code:
#include<stdio.h>
#include<conio.h>
void main()
{
int n,t,s,sq,ch,p,ln=0;
clrscr();
printf("\nenter no of processes : ");
scanf("%d",&n);
printf("\nenter which process is having the token");
scanf("%d",&t);
printf("\nenter status of process as 1 if executing the CS, 2 if
holding an idle token : ");
scanf("%d",&s);
printf("\nenter 1 if any process wants to enter into CS : ");
scanf("%d",&ch);
if(ch==1)
{
printf("\nenter process no.");
scanf("%d",&p);
printf("\nprocess %d sends request message ",p);}
Page |9
Lab Manual
Distributed System Lab
if(s==2)
{
printf("\n process %d is holding the token ",t);
printf("\n process %d passes token to process %d ",t,p);
printf("\nprocess %d enters into CS ",p);
}
if(s==1)
{
printf("\nprocess %d is executing in the CS so the request has
been buffered ",t);
printf("\nenter the sequence no : ");
scanf("%d",&sq);
delay(2000);
ln=sq;
printf("process %d passes token to process %d ",t,p);
printf("\nprocess %d enters into CS with sequence no %d ",p,ln);
}
getch();
}
Sample Input:
Enter no of process…. 3
Which process wants to enter into CS…. 1
Timestamp of process 1….. 2
All reply received
Sample Output:
Process 1 enters into CS with timestamp of 2
P a g e | 10
Lab Manual
Distributed System Lab
EXPERIMENT NO: 4
Objective: Write a program to execute the concept distributed mutual exclusion for
token based algorithm
Algorithm:
The Suzuki-Kasami algorithm is a token-based algorithm for achieving mutual
exclusion in distributed systems. If a process wants to enter the critical section, and it
does not have the token, it broadcasts a request message to all other processes in the
system.The processes that has the token will then send it to the requesting process F
However, if it is in CS, it gets to finish before sending the token. A process holding
the token can continuously enter the critical section until the token is requested
Request vector at process i : RNi[k]contains the largest sequence number received
from process k in a request message. Token consists of vector and a queue:
LN[k] contains the sequence number of the latest executed request from process k
Q is the queue of requesting process
Code:
#include<stdio.h>
P a g e | 11
Lab Manual
Distributed System Lab
#include<conio.h>
void main()
{
int n,t,c,a,s,p,seq;
clrscr();
printf("enter no of processes\n");
scanf("%d",&n);
printf("enter which process is having token\n");
scanf("%d",&t);
printf("enter status of process %d:1 for executing 0 for
holding\n",t);
scanf("%d",&c);
if(c==1)
{
printf("enter sequence no for process %d\n",t);
scanf("%d",&seq);
}printf("whether any process wants to enter CS:0 for no 1 for
yes\n");
scanf("%d",&a);
if(a==1)
{
printf("enter process no and sequence no\n");
scanf("%d%d",&p,&s);
printf("request message sent for process no %d with sequence no
%d\n",p,s);
if(c==0)
{
printf("pass token\n");
printf("%d enters CS\n",p);
}else if(c==1)
{
printf("buffer request\n");
delay(1000);
printf("pass token\n");
printf("LN=%d\n",seq);
printf("process %d enters CS\n",p);
}}
getch();
}
Sample Input:
Enter no of process…. 3
Which process is having token…. 1
Which process wants to enter into CS…. 2
Token passed
Sample Output:
Process 2 enters into CS
P a g e | 12
Lab Manual
Distributed System Lab
Q4. Token based Algorithms suffer with the problem of starvation. Explain a
method for solving the same.
Q5. Raymond’s tree-based algorithm for distributed mutual exclusion does not try
to order critical section requests based on time. So, the algorithm may be unfair. A
counter-argument to this statement of unfairness is that the hierarchical structure
of the tree built by the algorithm takes care of request ordering in an implicit way.
Explain whether Raymond’s distributed mutual exclusion algorithm is fair.
P a g e | 13
Lab Manual
Distributed System Lab
EXPERIMENT NO: 5
Algorithm:
RMI applications often comprise two separate programs, a server and a client. A
typical server program creates some remote objects, makes references to these objects
accessible, and waits for clients to invoke methods on these objects. A typical client
program obtains a remote reference to one or more remote objects on a server and
then invokes methods on them. RMI provides the mechanism by which the server and
the client communicate and pass information back and forth. Such an application is
sometimes referred to as a distributed object application.
Code:
AddServerIntf.java
import java.rmi.*;
public interface AddServerIntf extends Remote
{
double add(double d1, double d2) throws RemoteException;
double sub(double d1, double d2) throws RemoteException;
double mul(double d1, double d2) throws RemoteException;
double div(double d1, double d2) throws RemoteException;
}
AddServerImpl.java
import java.rmi.*;
import java.rmi.server.*;
public class AddServerImpl extends UnicastRemoteObject implements
AddServerIntf
{
public AddServerImpl() throws RemoteException
{
}
public double add(double d1, double d2) throws RemoteException
{
return d1+d2;
}}
AddServer.java
import java.net.*;
import java.rmi.*;
public class AddServer
{
public static void main(String [] args)
{
P a g e | 14
Lab Manual
Distributed System Lab
try
{
AddServerImpl addServerImpl = new AddServerImpl();
Naming.rebind("Addserver",addServerImpl);
}
catch(Exception e)
{
System.out.println("Exception: " +e);
}
}
}
AddClient.java
import java.rmi.*;
public class AddClient
{
public static void main(String args[])
{
try
{
String addServerURL = "rmi://" + args[0] + "/Addserver";
AddServerIntf addServerIntf =
(AddServerIntf)Naming.lookup(addServerURL);
System.out.println("the first number is :"+args[1]);
double d1 =Double.valueOf(args[1]).doubleValue();
System.out.println("the second number is :"+args[2]);
double d2 =Double.valueOf(args[2]).doubleValue();
System.out.println("The sum of two number is:" +
addServerIntf.add(d1,d2));
System.out.println("The difference of two number is:" +
addServerIntf.sub(d1,d2));
System.out.println("The multiplication of two number is:" +
addServerIntf.mul(d1,d2));
System.out.println("The division of two number is:" +
addServerIntf.div(d1,d2));
} catch (Exception e)
{
System.out.println(" Exception:" +e);
}}}
Sample Input:
Enter first no 3
Enter second no 3
Sample Output:
The addition is : 6
The subtraction is : 0
The division is : 1
The multiplication is : 9
P a g e | 15
Lab Manual
Distributed System Lab
Q4. Discuss the architecture of RMI?
Q5. What are the differences between Naming.bind() and Naming.rebind()?
Q6. How would you incorporate persistent asynchronous communication into a
model of communication based on RMIs to remote objects
P a g e | 16
Lab Manual
Distributed System Lab
EXPERIMENT NO: 6
Algorithm:
The Common Object Request Broker Architecture (CORBA) is an emerging open
distributed object computing infrastructure being standardized by the Object
Management Group. CORBA automates many common network programming tasks
such as object registration, location, and activation; request demultiplexing; framing
and error-handling; parameter marshalling and demarshalling; and operation
dispatching.
Code:
Hello.idl
module HelloApp
{
interface Hello
{
string sayHello();
oneway void shutdown();
};
};
HelloServer.java
import HelloApp.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.CORBA.*;
import org.omg.PortableServer.*;
import org.omg.PortableServer.POA;
import java.util.Properties;
class HelloImpl extends HelloPOA
private ORB orb;
public void setORB(ORB orb_val) {
orb = orb_val;
}
public String sayHello() {
return "\nHello world !!\n";
}
public void shutdown() {
orb.shutdown(false);
}
}
public class HelloServer {
public static void main(String args[]) {
try{
ORB orb = ORB.init(args, null);
POA rootpoa =
POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
rootpoa.the_POAManager().activate();
HelloImpl helloImpl = new HelloImpl();
helloImpl.setORB(orb);
P a g e | 17
Lab Manual
Distributed System Lab
org.omg.CORBA.Object ref =
rootpoa.servant_to_reference(helloImpl);
Hello href = HelloHelper.narrow(ref);
org.omg.CORBA.Object objRef =
orb.resolve_initial_references("NameService");
NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
String name = "Hello";
NameComponent path[] = ncRef.to_name( name );
ncRef.rebind(path, href);
System.out.println("HelloServer ready and waiting ...");
orb.run();
}
catch (Exception e) {
System.err.println("ERROR: " + e);
e.printStackTrace(System.out);
}
System.out.println("HelloServer Exiting ...");
}
}
HelloClient.java
import HelloApp.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.CORBA.*;
public class HelloClient
{
static Hello helloImpl;
public static void main(String args[])
{
try{
ORB orb = ORB.init(args, null);
org.omg.CORBA.Object objRef =
orb.resolve_initial_references("NameService");
NamingContextExt ncRef =
NamingContextExtHelper.narrow(objRef);
String name = "Hello";
helloImpl = HelloHelper.narrow(ncRef.resolve_str(name));
System.out.println("Obtained a handle on server object: " +
helloImpl);
System.out.println(helloImpl.sayHello());
helloImpl.shutdown();
} catch (Exception e) {
System.out.println("ERROR : " + e) ;
e.printStackTrace(System.out);
} } }
Sample Output:
Hello World!!!
Catch a object IOR…!!!
P a g e | 18
Lab Manual
Distributed System Lab
Q4. Discuss the architecture of CORBA?
Q5. Should the client and server-side objects for asynchronous method invocation
be persistent?
Q6. Is it possible to have system-specific implementations of CORBA object
references while still being able to exchange references with other CORBA based
systems?
P a g e | 19
Lab Manual
Distributed System Lab
EXPERIMENT NO: 7
Tools/ Language: C
Algorithm:
Remote procedure call (RPC) is an Inter-process communication technology that
allows a computer program to cause a subroutine or procedure to execute in another
address space (commonly on another computer on a shared network) without the
programmer explicitly coding the details for this remote interaction. That is, the
programmer would write essentially the same code whether the subroutine is local to
the executing program, or remote. When the software in question is written using
object-oriented principles, RPC may be referred to as remote invocation or remote
method invocation.
Code:
Date.x
program DATE_PROG {
version DATE_VERS {
long BIN_DATE(void) = 1; /* procedure number = 1 */
string STR_DATE(long) = 2; /* procedure number = 2 */
} = 1; /* version number = 1 */
} = 0x31234567;
Server
#include <time.h>
#include <rpc/rpc.h> /* standard RPC include file */
#include "date.h" /* this file is generated by rpcgen */
long *bin_date_1_svc(void *arg, struct svc_req *s)
{
static long timeval; /* must be static */
timeval = time((long *) 0);
return(&timeval);
}
char **str_date_1_svc(long *bintime, struct svc_req *s)
{
static char *ptr; /* must be static */
ptr = ctime((const time_t *)bintime); /* convert to local time */
return(&ptr);
}
Client
#include <stdio.h>
#include <rpc/rpc.h> /* standard RPC include file */
#include "date.h" /* this file is generated by rpcgen */
main(int argc, char *argv[])
{
CLIENT *cl; /* RPC handle */
char *server;
long *lresult; /* return value from bin_date_1() */
char **sresult; /* return value from str_date_1() */
if (argc != 2) {
fprintf(stderr, "usage: %s hostname\n", argv[0]);
exit(1);
P a g e | 20
Lab Manual
Distributed System Lab
}
server = argv[1];
if ((cl = clnt_create(server, DATE_PROG, DATE_VERS, "udp")) == NULL)
{
clnt_pcreateerror(server);
exit(2);
}
if ( (lresult = bin_date_1(NULL, cl)) == NULL) {
clnt_perror(cl, server);
exit(3);
}
printf("time on host %s = %ld\n",server, *lresult);
if ( (sresult = str_date_1(lresult, cl)) == NULL) {
clnt_perror(cl, server);
exit(4);
}
printf("time on host %s = %s", server, *sresult);
clnt_destroy(cl); /* done with the handle */
exit(0);
}
Sample Output:
The Date is : 22.04.2016 11:23:34 AM
P a g e | 21
Lab Manual
Distributed System Lab
EXPERIMENT NO: 8
Objective: Write a program to show that agreement cannot be reached if there is one
faulty processor out of three processors
Algorithm:
Byzantine Agreement (single source has an initial value)
Agreement: All non-faulty processes must agree on the same value.
Validity: If the source process is non-faulty, then the agreed upon value by all the
non-faulty processes must be the same as the initial value of the source.
Termination: Each non-faulty process must eventually decide on a value.
Code:
#include<stdio.h>
#include<conio.h>
#include<math.h>
void main()
{
int n,m,p1[5],p2[5],p3[5],f[5];
int i,p,v,c=0,d=0;
clrscr();
n=4;
printf("enter the no. of processes\n");
scanf("%d",&n); //4
printf("number of faulty process\n");
scanf("%d",&m); //1
printf("faulty process\n");
for(i=0;i<m;i++)
scanf("%d",&f[i]); //3
if(m<=floor((n-1)/3))
printf("agreement can be reached\n");
else
printf("agreement can't be reached\n");
printf("enter the source process\n");
scanf("%d",&p); // 1 process
printf(" initial value of source process is 1 \n");
v=1; //1
for(i=0;i<n-2;i++)
{
p1[i]=v;
p2[i]=v;
p3[i]=v;
}
for(i=0;i<n-2;i++)
if(i==f[i])
{
p1[i]=0;
p2[i]=0;
p3[i]=0;
}
printf("for process p1\n");
P a g e | 22
Lab Manual
Distributed System Lab
for(i=0;i<n-2;i++)
{
if(p1[i]==1)
c++;
else
d++;
}
if(c>d)
printf("agree!!!!\n");
getch();
}
Sample Input:
N= 5, m= 1
Source processor is: 1
Initial value is 1
Sample Output:
Agreement can be reached on value 1
P a g e | 23
Lab Manual
Distributed System Lab
EXPERIMENT NO: 9
Tools/ Language: C
Algorithm:
Code:
server.c
import java.net.*;
import java.io.*;
public class servertcp
{
public static void main(String args[]) throws IOException
{
ServerSocket ss=new ServerSocket(12);
Socket s=ss.accept();
System.out.println("Connection from "+s);
PrintWriter pw1=new PrintWriter(s.getOutputStream(),true);
BufferedReader br3=new BufferedReader(new
InputStreamReader(s.getInputStream()));
BufferedReader br4=new BufferedReader(new
InputStreamReader(System.in));
System.out.println("i m ready");
String s1, s2;
/*while((s1=br4.readLine())!=null)
{
pw1.println(s1);
System.out.println(s2);
}
*/
while(true)
{
do
{
s1=br4.readLine();
pw1.println(s1);
}
while(!s1.equals("over"));
do
{
s2=br3.readLine();
System.out.println(s2);
}
while(!s2.equals("over"));
P a g e | 24
Lab Manual
Distributed System Lab
}
}
}
Client.c
import java.net.*;
import java.io.*;
public class clienttcp
{
public static void main(String args[]) throws IOException
{
Socket cc=new Socket(InetAddress.getLocalHost(),12);
PrintWriter pw=new PrintWriter(cc.getOutputStream(),true);
BufferedReader br1=new BufferedReader(new
InputStreamReader(cc.getInputStream()));
BufferedReader br2=new BufferedReader(new
InputStreamReader(System.in));
String str1, str2;
/*while((str1=br2.readLine())!=null)
{
System.out.println(str1);
//pw.println(str2);
}
*/
while(true)
{
do
{
str1=br1.readLine();
System.out.println(str1);
}
while(!str1.equals("over"));
do
{
str2=br2.readLine();
pw.println(str2);
}
while(!str2.equals("over"));
}}}
Sample Output:
At server: Hi!!!
At Client: Hi!!
P a g e | 25
Lab Manual
Distributed System Lab
receive data and the size of this data could be large.(about 5MB). Design the
program for the same using TCP Sockets
P a g e | 26