Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 40

IIMT COLLEGE OF ENGINEERING, GREATER NOIDA

Department of Computer Science & Engineering

Session: 2019-20 Semester: VII Section: B


Subject Code: RCS751 Lab Name: Distributed System Lab
Prerequisite of the course (subject):
Distributed System RCS-701

Course Outcomes (COs):


CO1• Identify the advantages and challenges in designing distributed algorithms for different
primitives like Mutual exclusion, deadlock detection, agreement, etc.

C02• Design and develop distributed programs using sockets and RPC/RMI.
CO3 • Differentiate between different types of faults and fault handling techniques in order to
implement fault Tolerant systems
.
CO4• Analyze different algorithms and techniques for the design and development of distributed
Systems subject to specific design and performance constraints
.
Program List Prescribed by University

S. No. CO Programs

1 CO1 Simulate the functioning of Lamport’s Logical Clock in ‘C’.


2 CO1 Simulate the Distributed Mutual Exclusion in ‘C’.
3 CO2 Implement a Distributed Chat Server using TCP Sockets in
‘C’.
4 CO2,CO4 Implement RPC mechanism for a file transfer across a
network in ‘C’
5 CO2 Implement ‘Java RMI’ mechanism for accessing methods of
remote systems.
6 CO3, Simulate Balanced Sliding Window Protocol in ‘C’.
7 CO2,CO4 Implement CORBA mechanism by using ‘C++’ program at
one end and ‘Java program on the other.

List of Augmented Program:


1: To write a Program for multi-threaded client/server processes.

Course Incharge
Experiment List Prepared for this Session
S.No. Program Name Student Date Faculty Remark
Signature Signature
1 To Simulate
the
functioning of
Lamport’s
Logical clock
in ‘c’..

2 To Simulate
the
functioning of
Lamport’s
Vector clock
in ‘c’

3 To Simulate
the
Distributed
Mutual
exclusion in
‘c’.

4 To Simulate
the Non
Token based
algorithm-
Lamport’s

5 To Simulate
the Token
based
algorithm-
Raymond’s.
6 To Simulate
the
Distributed
Deadlock
Detection
algorithm-
Edge chasing.

7 To
Implement
‘Java RMI’
mechanism
for accessing
methods of
remote
systems.
8 To Simulate
balanced
sliding
Window
protocol in
‘c’.

9 To
implement a
distributed
chat server
using TCP
socket in C.

10 To
implement
CORBA
mechanism
by using C++
program at
one end and
Java Program
on the other.
Introduction
Distributed computing is a field of computer science that studies distributed systems.
A distributed system is a model in which components located on networked computers
communicate and coordinate their actions by passing messages. The components interact with
each other in order to achieve a common goal. Three significant characteristics of distributed
systems are: concurrency of components, lack of a global clock, and independent failure of
components. Examples of distributed systems vary from SOA-based systems to massively
multiplayer online games to peer-to-peer applications.

A computer program that runs in a distributed system is called a distributed program, and
distributed programming is the process of writing such programs. There are many alternatives
for the message passing mechanism, including pure HTTP, RPC-like connectors and message
queues.

A goal and challenge pursued by some computer scientists and practitioners in distributed
systems is location transparency; however, this goal has fallen out of favour in industry, as
distributed systems are different from conventional non-distributed systems, and the
differences, such as network partitions, partial system failures, and partial upgrades, cannot
simply be "papered over" by attempts at "transparency".
Experiment#1
Experiment Text: To Simulate the functioning of Lamport’s Logical clock in ‘c’

Prerequisites: Global Clock Concept, C programming

Outcome: Program will exhibit the simulation of Lamport’ logical clock behaviour based on
two rules.

What Student will learn? As discussed in class student will learn how this experiment can
decide happened before relation between any two event on same process and across the
processes.

Description: The "time" concept in distributed systems -- used to order events in a distributed
system.

Assumption:

o The execution of a process is characterized by a sequence of events. An


event can be the execution of one instruction or of one procedure.
o Sending a message is one event, receiving a message is one event.
o The events in a distributed system are not total chaos. Under some conditions,
it is possible to ascertain the order of the events. Lamport's logical clocks try
to catch this.

Lamport's `happened before'' relation

The ``happened before'' relation (®) is defined as follows:

 A ® B if A and B are within the same process (same sequential thread of


 control) and A occurred before B.
 A ® B if A is the event of sending a message M in one process and B is the event
 of receiving M by another process
 if A ® B and B ® C then A ® C

Event A causally affects event B iff A ® B.

Distinct events A and B are concurrent (A | | B) if we do not have A ® B or B ® A.

Algorithm:
Ci is the local clock for process Pi

 if a and b are two successive events in Pi,


 then Ci(b) = Ci(a) + d1, where d1 > 0
 if a is the sending of message m by Pi, then m is
 assigned timestamp tm = Ci(a)
 if b is the receipt of m by Pj, then
Cj(b) = max{Cj(b), tm + d2}, where d2 > 0
Code:
#include <conio.h>

#include <stdio.h>

#include <stdlib.h>

void main()
{

int i,j,k; int x=0;


char a[10][10];
int n,num[10],b[10][10]; clrscr();
printf("Enter the no. of physical clocks: "); scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("\nNo. of nodes for physical clock %d",i+1); scanf("%d",&num[i]);
x=0;
for(j=0;j<num[i];j++)
{
printf("\nEnter the name of process: ");
scanf("%s",&a[i][j]); b[i][j]=x + rand() % 10; x=b[i][j]+1;
}
}

printf("\nPress a key for watching timestamp of physical clocks"); getch();


clrscr();
for(i=0;i<n;i++)
{
printf("Physical Clock %d",i+1); for(j=0;j<num[i];j++)
{
printf("\nProcess %c",a[i][j]); printf(" has P.T. :%d ",b[i][j]);
printf("\n");
}
}

printf("Press a key for watching timestamp of logical clocks"); getch();


clrscr();
x=0;
for(i=0;i<10;i++)
for(j=0;j<n;j++)
for(k=0;k<num[j];k++)
if(b[j][k]==i)
{
x = rand() % 10 + x;
lock Timestamp for process %c",a[j][k]); printf(":%d
",x); printf("\n");
}
getch();
return;
}
Expected Output:

Enter the no. of physical clocks: 2

No. of nodes for physical clock 1: 2


Enter the name of process: a
Enter the name of process: b

No. of nodes for physical clock 2: 2


Enter the name of process: c
Enter the name of process: d

Press a key for watching timestamp of physical clocks

Physical Clock 1
Process a has P.T.: 6
Process b has P.T.: 7

Physical Clock 2
Process c has P.T.: 2
Process d has P.T.: 3

Press a key for watching timestamp of logical clocks

Logical Clock Timestamp for process a: 6


Logical Clock Timestamp for process b: 13
Logical Clock Timestamp for process c: 18
Logical Clock Timestamp for process d: 23

Applications: With a limitation of using for transitive dependency, it can be


used to decide causal ordering for any two events in distributed systems.
Experiment#2
Experiment Text: Simulate the functioning of Lamport’s Vector clock in ‘c’

Prerequisites: Vector clock functioning, C programming

Outcome: Causal ordering for transitive processes

What Student will learn? Student will be able to calculate happened before relationship even
for unrelated processes.

Description: Vector Clocks are used in distributed systems to determine whether pairs of
events are causally related. Using Vector Clocks, timestamps are generated for each event in
the system, and their causal relationship is determined by comparing those timestamps.

The timestamp for an event is an n-tuple of integers, where n is the number of processes.

Each process assigns a timestamp to each event. The timestamp is composed of that process
logical time and the last known time of every other process.

Algorithm:
ta < tb If and only if they meet two conditions:

1.They are not equal timestamps ( there exists i, ta[i] != tb[i]) and

2.each ta[i] is less than or equal to tb[i] (for all i, ta[i] <= tb[i])

Code:
#include<stdio.h>
#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
long *p1(int i,long *comp);
long *p2(int i,long *comp);
long *p3(int i,long *comp);
void main()
{
long start[]={0,0,0},*vector;
clrscr();
while(!kbhit())
{
p1(1,&start[0]);
}
printf("\n Process Vector\n");
vector=p1(0,&start[0]);
printf("p1[%ld%ld%ld]\n",*vector,*(vector+1),*(vector+2));
vector=p2(0,&start[0]);
printf("p2[%ld%ld%ld]\n",*vector,*(vector+1),*(vector+2));
vector=p3(0,&start[0]);
printf("p3[%ld%ld%ld]\n",*vector,*(vector+1),*(vector+2));
}
long *p1(int i,long *comp)
{
static long a[]={0,0,0};
int next;
if(i==1)
{
a[0]++;
if(*(comp+1)>a[1])
a[1]=*(comp+1);
if(*(comp+2)>a[2])
a[2]=*(comp+2);
next=random(2);
if(next==0)
p2(1,&a[0]);
else if(next==1)
p3(1,&a[0]);
return(&a[0]);
}
else
return(&a[0]);
}
long *p2(int i,long *comp)
{
static long b[]={0,0,0};
int next;
if(i==1)
{
b[i]++;
if(*comp>b[0])
b[0]=*(comp);
if(*(comp+2)>b[2])
b[2]=*(comp+2);
next=random(2);
if(next==0)
p1(1,&b[0]);
else if(next==1)
p3(1,&b[0]);
return &b[0];
}
else
return &b[0];
}
long *p3(int i,long *comp)
{
static long c[]={0,0,0};
int next;
if(i==1)
{
c[2]++;
if(*comp>c[0])
c[0]=*(comp);
if(*(comp+1)>c[1])
c[1]=*(comp+1);
next=random(2);
if(next==0)
p1(1,&c[0]);
return &c[0];
}
else return &c[0];}
Expected Output:

Applications: In deciding Ordering of events as each process carries vector


Experiment#3
Experiment Text: To Simulate the Distributed Mutual exclusion in ‘c’.

Prerequisites: Mutual exclusion concepts, C programming

Outcome: Procedure of mutual exclusion for distributed systems

What Student will learn? Student will learn how processes share resources on the basis of
mutual exclusion.

Description: Concurrent access of processes to a shared resource or data is executed in mutually


exclusive manner. Only one process is allowed to execute the critical section (CS) at any given time. In
a distributed system, shared variables (semaphores) or a local kernel cannot be used to implement
mutual exclusion. Message passing is the sole means for implementing distributed mutual exclusion.

Algorithm:
Process 1: Request resource:


Resource Allocated No more requests process for this resource

Process2: Request Resource Denied
Process 1: Exit Resource:


Process2: Request Resource Allocated

Code:

#include<stdio.h>
#include<conio.h>
#include<dos.h>
#include<time.h>

void main()
{
int cs=0,pro=0; double run=5; char key='a'; time_t t1,t2;

clrscr();
printf("Press a key(except q) to enter a process into critical section."); printf(" \nPress
q at any time to exit.");
t1 = time(NULL) - 5; while(key!='q')
while(!kbhit())
if(cs!=0)
{
t2 = time(NULL);if(t2-t1 > run)
{
printf("Process%d ",pro-1);printf(" exits
critical section.\n");
cs=0;
}
}
key = getch(); if(key!='q')
{
if(cs!=0)
printf("Error: Another process is currently
executing critical section Please wait till its execution is
over.\n");
else
{
printf("Process %d ",pro);
printf(" entered critical section\n");
cs=1; pro++;
t1 = time(NULL);
}
}
}
}

Expected Output:

Press a key (except q) to enter a process into critical section. Press q at any time to exit.

Process 0 entered critical section.

or: Another process is currently executing critical section. Please wait till its execution
is over.

Process 0 exits critical section.

Process 1 entered critical section.

Process 1 exits critical section.

Process 2 entered critical section.

or: Another process is currently executing critical section. Please wait till its execution
is over.

Process 2 exits critical section.


Applications: Resource Sharing exclusion
Experiment#4
Experiment Text: To Simulate the Non Token based algorithm-Lamport’s

Prerequisites: Understanding of Non-Token based algorithm, Java programming

Outcome: Implementation of Non-token based lamport’s algorithm behaviour

What Student will learn? Student will learn the behaviour of Non-Token based algorithm for
mutual exclusion

Description: Requests for CS are executed in the increasing order of timestamps and time is
determined by logical clocks. Every site Si keeps a queue, request queuei , which contains mutual
exclusion requests ordered by their timestamps. This algorithm requires communication channels to
deliver messages the FIFO order.

Algorithm:

Requesting the critical section:

When a site Si wants to enter the CS,

it broadcasts a REQUEST(tsi , i) message to all other sites and places the request on request queuei .
((tsi , i) denotes the timestamp of the request.)

When a site Sj receives the REQUEST(tsi , i) message from site Si ,

places site Si ’s request on request queuej and it returns a timestamped REPLY message to Si .

Executing the critical section: Site Si enters the CS when the following two conditions hold:

L1: Si has received a message with timestamp larger than (tsi , i) from all other sites.

L2: Si ’s request is at the top of request queuei .

Code:

import java.util.*;
class lamport

public static void main(String args[])


{

int ts1,ts2,ts3,req1=0,req2=0,req3=0;

Scanner sc=new Scanner(System.in);

System.out.print(“Enter Time Stamp for Site S1 :”);

ts1=Integer.parseInt(sc.next());
System.out.print(“Enter Time Stamp for Site S2 :”);
ts2=Integer.parseInt(sc.next());
System.out.print(“Enter Time Stamp for Site S3 :”);
ts3=Integer.parseInt(sc.next());
System.out.print(“Is Site S1 Send a CS request : Y/N =”);

String res=sc.next();

if(res.equalsIgnoreCase(“y”))

req1=1;

System.out.print(“Is Site S2 Send a CS request : Y/N =”);


res=sc.next();
if(res.equalsIgnoreCase(“y”))

req2=1;

System.out.print(“Is Site S3 Send a CS request : Y/N =”);


res=sc.next();
if(res.equalsIgnoreCase(“y”))

req3=1;

q obj2=new q();

obj2.ts=ts2;

obj2.si=2;
q obj1=new q();

obj1.ts=ts1;

obj1.si=1;

q obj3=new q();

obj3.ts=ts3;

obj3.si=3;

q obj4=new q();

obj4.ts=ts3;

obj4.si=100;

if(req2==1)

lamport l1=new lamport();

l1.stack(obj2,obj1,1);

lamport l2=new lamport();

l2.stack(obj2,obj3,2);

}
lamport l3=new lamport();

if(req1==1)

l3.stack(obj1,obj2,1);

lamport l4=new lamport();

l4.stack(obj1,obj3,2);

if(req3==1)

lamport l5=new lamport();

l5.stack(obj3,obj1,1);

lamport l6=new lamport();

l6.stack(obj3,obj2,2);

if(req1==1)

System.out.println(“REQUEST(S1) :[ (“+obj1.a.ts+”,”+obj1.a.si+”)(“+obj1.b.ts+”,”+obj1.b.si+”)]”);

System.out.println(“REQUEST(S1) :[ (“+obj1.c.ts+”,”+obj1.c.si+”)(“+obj1.d.ts+”,”+obj1.d.si+”)]”); }
if(req2==1)

System.out.println(“REQUEST(S2) :[ (“+obj2.a.ts+”,”+obj2.a.si+”)(“+obj2.b.ts+”,”+obj2.b.si+”)]”);

System.out.println(“REQUEST(S2) :[ (“+obj2.c.ts+”,”+obj2.c.si+”)(“+obj2.d.ts+”,”+obj2.d.si+”)]”); }

if(req3==1)

System.out.println(“REQUEST(S3) :[ (“+obj3.a.ts+”,”+obj3.a.si+”)(“+obj3.b.ts+”,”+obj3.b.si+”)]”);

System.out.println(“REQUEST(S3) :[ (“+obj3.c.ts+”,”+obj3.c.si+”)(“+obj3.d.ts+”,”+obj3.d.si+”)]”); }

if((obj2.a.ts==obj2.c.ts)&&(obj2.a.si==obj2.c.si)&&(obj2.a.si==2))

System.out.println(” SIte S2 Executing in CS “);


l3.rel(obj2,obj2,1);l3.rel(obj2,obj2,2);

l3.rel(obj2,obj1,1);

System.out.println(” After Releasing CS “);

System.out.println(“REQUEST(S2) :[ (“+obj2.a.ts+”,”+obj2.a.si+”)]”);

System.out.println(“REQUEST(S2) :[ (“+obj2.c.ts+”,”+obj2.c.si+”)]”);

System.out.println(“REQUEST(S1) :[ (“+obj1.a.ts+”,”+obj1.a.si+”)(“+obj1.b.ts+”,”+obj1.b.si+”)]”);

System.out.println(“REQUEST(S1) :[ (“+obj1.c.ts+”,”+obj1.c.si+”)(“+obj1.d.ts+”,”+obj1.d.si+”)]”);
System.out.println(” SIte S1 Executing in CS “);
}}

public void stack(q objcal,q objcmp,int r)

if((objcal.ts)<(objcmp.ts
{

if(r==1)

objcal.a=objcal;

objcal.b=objcmp;

else

objcal.c=objcal;

objcal.d=objcmp;

else

{
if(r==1)

objcal.b=objcal;

objcal.a=objcmp;

else

objcal.d=objcal;

objcal.c=objcmp;

public void rel(q objcl,q objrm,int rm)

if(objcl.a.si==objrm.a.si)

if(rm==1)

objrm.a=objrm.b;
objrm.b=null;

else

objrm.c=objrm.d;

objrm.b=null;

}}

class q

int ts,si;

q a;

q b;

q c;

q d;

Expected Output: The process which would have next to on ring would access resource.

Applications: Prevention of deadlock


Experiment#5
Experiment Text: To Simulate the Token based algorithm- Raymond’s.

Prerequisites: Understanding of Raymond’s algorithm

Outcome: Behaviour of token based algorithm- Raymond’s

Description:

The mutual exclusion problem is an important problem in distributed systems. The fairness
property is a crucial attribute of distributed mutual exclusion algorithms. All solutions to the
distributed mutual exclusion problem are expected to implement at least starvation freedom
as the fairness criterion. In certain situations, a stronger fairness criterion is desirable. In this
paper, we have substantially modified Raymond's tree based distributed mutual exclusion
algorithm to incorporate such a fairness criterion, viz., the least executed criterion. The lower
and upper bounds on the number of messages generated per critical section execution are 0
and 2D respectively, where D is the diameter of a spanning tree of the distributed system.
These bounds are the same as those of Raymond's algorithm.

Algorithm:

Nodal Properties

1. Each node has only one parent to whom received requests are forwarded
2. Each node maintains a FIFO queue of requests each time that it sees the token;
3. If any node is forwarding privilege to other node and has non-empty queue then it
forwards a request message along
Algorithm

1. If a node i wish to receive the token in order to enter into its critical section, it sends a
request to its parent, node j.
 If node j FIFO is empty, node j shifts i into the its FIFO queue; j then issues a
request to its parent, k, that it desires the token

 If node j FIFO queue is not empty, it simply shifts i into the queue

2. When node j receives the token from k, it forwards the token to i and i is removed from
the queue of j
 If the queue of j is not empty after forwarding the token to i, j must issue a request
to i in order to get the token back

Note: If j wishes to request a token, and its queue is not empty, then it places itself into its own
queue. Node j will utilize the token to enter into its critical section if it is at the head of the
queue when the token is received.

Expected Output: Process to request for token and grant


Applications: How token travels through parents.
Experiment#6
Experiment Text: To Simulate the Distributed Deadlock Detection algorithm-Edge
chasing.

Prerequisites: Deadlock knowledge, C compiler,

Outcome: Detect whether deadlock has occurred or not

Description & Algorithm:

Whenever a process A is blocked for some resource, a probe message is sent


to all processes A may depend on. The probe message contains the process id
of A along with the path that the message has followed through the distributed
system. If a blocked process receives the probe it will update the path
information and forward the probe to all the processes it depends on. Non-
blocked processes may discard the probe.

If eventually the probe returns to process A, there is a circular waiting loop of


blocked processes, and a deadlock is detected. Efficiently detecting such cycles
in the “wait-for graph” of blocked processes is an important implementation
problem.

Expected Output: The status of the system as deadlocked or not

Applications: To get the system bottleneck


Experiment#7
Experiment Text: To Implement ‘Java RMI’ mechanism for accessing methods of remote systems

Prerequisites: Knowledge of remoting, Java

Outcome: Method of remote location will perform computation

Description: The Java Remote Method Invocation (Java RMI) is a Java API that
performs remote method invocation, the object-oriented equivalent of remote procedure
calls (RPC), with support for direct transfer of serialized Java classes and distributed garbage
collection.

1. The original implementation depends on Java Virtual Machine (JVM) class representation
mechanisms and it thus only supports making calls from one JVM to another. The
protocol underlying this Java-only implementation is known as Java Remote Method
Protocol (JRMP).
2. In order to support code running in a non-JVM context, a CORBA version was later
developed.

Usage of the term RMI may denote solely the programming interface or may signify both the
API and JRMP, IIOP, or another implementation, whereas the term RMI-IIOP (read: RMI over
IIOP) specifically denotes the RMI interface delegating most of the functionality to the
supporting CORBA implementation.

The basic idea of Java RMI, the distributed garbage-collection (DGC) protocol, and much of the
architecture underlying the original Sun implementation, come from the 'network objects' feature
of Modula-3.
Code:

RMI SERVER:

import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.registry.*;
public class RmiServer extends UnicastRemoteObject implements
RmiServerIntf {
public static final String MESSAGE = "Hello World";

public RmiServer() throws RemoteException {


super(0); // required to avoid the 'rmic' step, see below
}
public String getMessage() {
return MESSAGE;
}

public static void main(String args[]) throws Exception


{ System.out.println("RMI server started");

try { //special exception handler for registry creation


LocateRegistry.createRegistry(1099);
System.out.println("java RMI registry created.");
} catch (RemoteException e) {
//do nothing, error means registry already exists
System.out.println("java RMI registry already exists.");
}

//Instantiate RmiServer

RmiServer obj = new RmiServer();

// Bind this object instance to the name "RmiServer"


Naming.rebind("//localhost/RmiServer", obj);
System.out.println("PeerServer bound in registry");
}
}

INTERFACE

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface RmiServerIntf extends Remote {


public String getMessage() throws
RemoteException;
}

CLIENT

import java.rmi.Naming;

public class RmiClient {


public static void main(String args[]) throws Exception
{ RmiServerIntf obj =
(RmiServerIntf)Naming.lookup("//localhost/RmiServer");
System.out.println(obj.getMessage());
}
}

Expected Output: Client can access the method of given by server using interface

Applications: Vast application as remote method access


Experiment#8
Experiment Text: : To Simulate balanced sliding Window protocol.

Prerequisites: Knowledge of sliding window protocol

Outcome: Implementation of sliding window protocol

Description:

A sliding window protocol is a feature of packet-based data transmission protocols. Sliding


window protocols are used where reliable in-order delivery of packets is required, such as in
the Data Link Layer (OSI model) as well as in the Transmission Control Protocol (TCP).

Conceptually, each portion of the transmission (packets in most data link layers, but bytes in
TCP) is assigned a unique consecutive sequence number, and the receiver uses the numbers to
place received packets in the correct order, discarding duplicate packets and identifying missing
ones. The problem with this is that there is no limit on the size of the sequence number that can
be required.

Algorithm:

The sequence numbers always obey the rule that na ≤ nr ≤ ns ≤ nt ≤ na + wt. That is:

 na ≤ nr: The highest acknowledgement received by the transmitter cannot be higher than
the highest nr acknowledged by the receiver.

 nr ≤ ns: The span of fully received packets cannot extend beyond the end of the partially
received packets.

 ns ≤ nt: The highest packet received cannot be higher than the highest packet sent.

 nt ≤ na + wt: The highest packet sent is limited by the highest acknowledgement received and
the transmit window size.
Transmitter operation
Whenever the transmitter has data to send, it may transmit up to wt packets ahead of the latest
acknowledgment na. That is, it may transmit packet number nt as long as nt <na+wt.

In the absence of a communication error, the transmitter soon receives an acknowledgment for
all the packets it has sent, leaving na equal to nt. If this does not happen after a reasonable delay,
the transmitter must retransmit the packets between na and nt.

Techniques for defining "reasonable delay" can be extremely elaborate, but they only affect
efficiency; the basic reliability of the sliding window protocol does not depend on the details.

Receiver operation
Every time a packet numbered x is received, the receiver checks to see if it falls in the receive
window, nr ≤ x < ns+wr. (The simplest receivers only have to keep track of one value nr=ns.) If it falls
within the window, the receiver accepts it. If it is numbered nr, the receive sequence number

is increased by 1, and possibly more if further consecutive packets were previously received and
stored. If x > nr, the packet is stored until all preceding packets have been received.[1] If x≥ns, the
latter is updated to ns=x+1.

If the packet's number is not within the receive window, the receiver discards it and does not
modify nr or ns.

Whether the packet was accepted or not, the receiver transmits an acknowledgment
containing the current nr. (The acknowledgment may also include information about additional
packets received between nr or ns, but that only helps efficiency.)

Note that there is no point having the receive window wr larger than the transmit window wt,
because there is no need to worry about receiving a packet that will never be transmitted; the
useful range is 1 ≤ wr ≤ wt.
Code:

1. slic.java

//SLIDING WINDOW PROTOCOL – CLIENT


import java.io.*;
import java.net.*;

public class slic{


public static void main(String args[])throws Exception{
Socket s = new Socket(“local host”,8888);
Buffered Reader from server = new BufferReader(new
InputStreamReader(s.getInputStream()));
DataOutputStream toserver = new DataOutputStream(s.getOutputStream());
BufferedReader d = new BufferedReader(new
InputStreamReader(System.in)); String dout,din;
System.out.println(“\t”+fromserver.readLine());
System.out.println(“enter quit to exit”);
System.out.println(“enter data for server :”);

While(true)
{
Dout = d.readLine();
If(dout.equals(“quit”))
Break;
toserver.writeBytes(dout+’\n’);
din = fromserver.readLine();
System.out.println(“Server :”+din);
System.out.println(“\nEnter for server :”);
}
}
}
2. slis.java

//SLIDING WINDOW PROTOCOL – SERVER


import java.io.*;
import java.net.*;

public class slis{


public static void main(String args[])throws Exception{
ServerSocket ss = new ServerSocket(8888);
System.out.println(“\t waiting for client…”);
Socket client = ss.accept();
BufferedReader fromclient = new BufferedReader(new
InputStreamReader(client.getInputStream()));
DataOutputStream toclient = new
DataOutputStream(client.getOutputStream()); BufferedReader
d = new BufferedReader(new InputStreamReader(System.in));
String dout,din;
toclient.writeBytes(“Server ready….”+’\n’);

while(true){
din = fromclient.readLine();
System.out.println(“\n client data:”+din);
System.out.println(“enter for client :”);
dout = d.readLine();
if(dout.equals(“quit”))
break;
toclient.writeBytes(dout+’\n’);
}
}
}
Expected Output: Demonstration of sliding window

Applications: Packet transmission


Experiment#9
Experiment Text: To implement a distributed chat server using TCP socket in C.

Prerequisites: Socket manual, C

Outcome: Client and server program interaction using chat

What Student will learn? Lowest scalable possible behaviour of Distributed systems

Description: Sockets allow communication between two different processes on the same or
different machines. To be more precise, it's a way to talk to other computers using standard
Unix file descriptors. In Unix, every I/O action is done by writing or reading a file descriptor.
A file descriptor is just an integer associated with an open file and it can be a network
connection, a text file, a terminal, or something else.

To a programmer, a socket looks and behaves much like a low-level file descriptor. This is
because commands such as read() and write() work with sockets in the same way they do with
files and pipes.

Code:

SERVER
#include<stdio.h>
#include<netinet/in.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netdb.h>
#include<stdlib.h>
#include<string.h>
#define MAX 80
#define PORT 43454
#define SA struct sockaddr
void func(int sockfd)
{
char buff[MAX];
int n;
for(;;)
{
bzero(buff,MAX);
read(sockfd,buff,sizeof(buff));
printf("From client: %s\t To client : ",buff);
bzero(buff,MAX);
n=0;
while((buff[n++]=getchar())!='\n');
write(sockfd,buff,sizeof(buff));
if(strncmp("exit",buff,4)==0)
{
printf("Server Exit...\n");
break;
}
}
}
int main()
{
int sockfd,connfd,len;
struct sockaddr_in servaddr,cli;
sockfd=socket(AF_INET,SOCK_STREAM,0);
if(sockfd==-1)
{
printf("socket creation failed...\n");
exit(0);
}
else
printf("Socket successfully created..\n");
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
servaddr.sin_port=htons(PORT);
if((bind(sockfd,(SA*)&servaddr, sizeof(servaddr)))!=0)
{
printf("socket bind failed...\n");
exit(0);
}
else
printf("Socket successfully binded..\n");
if((listen(sockfd,5))!=0)
{
printf("Listen failed...\n");
exit(0);
}
else
printf("Server listening..\n");
len=sizeof(cli);
connfd=accept(sockfd,(SA *)&cli,&len);
if(connfd<0)
{
printf("server acccept failed...\n");
exit(0);
}
else
printf("server acccept the client...\n");
func(connfd);
close(sockfd);
}

CLIENT
#include<stdio.h>
#include<netinet/in.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netdb.h>
#include<string.h>
#include<stdlib.h>
#define MAX 80
#define PORT 43454
#define SA struct sockaddr
void func(int sockfd)
{
char buff[MAX];
int n;
for(;;)
{
bzero(buff,sizeof(buff));
printf("Enter the string : ");
n=0;
while((buff[n++]=getchar())!='\n');
write(sockfd,buff,sizeof(buff));
bzero(buff,sizeof(buff));
read(sockfd,buff,sizeof(buff));
printf("From Server : %s",buff);
if((strncmp(buff,"exit",4))==0)
{
printf("Client Exit...\n");
break;
}
}
}

int main()
{
int sockfd,connfd;
struct sockaddr_in servaddr,cli;
sockfd=socket(AF_INET,SOCK_STREAM,0);
if(sockfd==-1)
{
printf("socket creation failed...\n");
exit(0);
}
else
printf("Socket successfully created..\n");
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin_addr.s_addr=inet_addr("127.0.0.1");
servaddr.sin_port=htons(PORT);
if(connect(sockfd,(SA *)&servaddr,sizeof(servaddr))!=0)
{
printf("connection with the server failed...\n");
exit(0);
}
else
printf("connected to the server..\n");
func(sockfd);
close(sockfd);
}

Expected Output:

SERVER SIDE
$ cc tcpchatserver.c
$ ./a.out
Socket successfully created..
Socket successfully binded..
Server listening..
server acccept the client...
From client: hai
To client : hello
From client: exit
To client : exit
Server Exit...
$

CLIENT SIDE
$ cc tcpchatclient.c
$ ./a.out
Socket successfully created..
connected to the server..
Enter the string : hai
From Server : hello
Enter the string : exit
From Server : exit
Client Exit...

Applications:

To implement Client –server architecture


Experiment#10
Experiment Text: To implement CORBA mechanism by Java Program .

Prerequisites:

Outcome:

What Student will learn?

Description:

Algorithm:

Code:

1.FileInterface.idl

interface FileInterface {
typedef sequence<octet> Data;
Data downloadFile(in string fileName);
};

Now, let's compile the FileInterface.idl and generate server-side skeletons. Using
the command:

D:\Prakash\RND\Java\CORBA> idlj -fserver FileInterface.idl

2.FileServant.java

import java.io.*;

public class FileServant extends _FileInterfaceImplBase


{ public byte[] downloadFile(String fileName){
File file = new File(fileName);
byte buffer[] = new byte[(int)file.length()];
try {
BufferedInputStream input = new
BufferedInputStream(new FileInputStream(fileName));
input.read(buffer,0,buffer.length);
input.close();
} catch(Exception e) {
System.out.println("FileServant Error: "+e.getMessage());
e.printStackTrace();
}
return(buffer);
}
}

3.FileServer.java

import java.io.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.CORBA.*;

public class FileServer {


public static void main(String args[]) {
try{
// create and initialize the ORB
ORB orb = ORB.init(args, null);
// create the servant and register it with the
ORB FileServant fileRef = new FileServant();
orb.connect(fileRef);
// get the root naming context
org.omg.CORBA.Object objRef =
orb.resolve_initial_references("NameService"); NamingContext
ncRef = NamingContextHelper.narrow(objRef);
// Bind the object reference in naming
NameComponent nc = new NameComponent("FileTransfer", " ");
NameComponent path[] = {nc};
ncRef.rebind(path, fileRef);
System.out.println("Server started....");
// Wait for invocations from clients
java.lang.Object sync = new
java.lang.Object(); synchronized(sync){
sync.wait();
}
} catch(Exception e) {
System.err.println("ERROR: " + e.getMessage());
e.printStackTrace(System.out);
}
}
}

4.FileClient.java

import java.io.*;
import java.util.*;
import org.omg.CosNaming.*;
import org.omg.CORBA.*;

public class FileClient {


public static void main(String argv[]) {
try {
// create and initialize the ORB
ORB orb = ORB.init(argv, null);
// get the root naming context
org.omg.CORBA.Object objRef =
orb.resolve_initial_references("NameService"); NamingContext
ncRef = NamingContextHelper.narrow(objRef); NameComponent
nc = new NameComponent("FileTransfer", " ");
// Resolve the object
reference in naming
NameComponent path[]
= {nc};
FileInterfaceOperations
fileRef =
FileInterfaceHelper.narrow(ncRef.resolve(path));

if(argv.length < 1) {
System.out.println("Usage: java FileClient filename");
}

// save the file


File file = new File(argv[0]);
byte data[] = fileRef.downloadFile(argv[0]);
BufferedOutputStream output = new
BufferedOutputStream(new
FileOutputStream(argv[0]));
output.write(data, 0, data.length);
output.flush();
output.close();
} catch(Exception e) {
System.out.println("FileClient Error: " +
e.getMessage());
e.printStackTrace();
}
}
}

Running the application

1. D:\Test\RND\Java\CORBA>tnameserv
2. D:\ Test \RND\Java\CORBA>java FileServer
3. D:\ Test \RND\Java\CORBA>idlj -fclient FileInterface.idl
4. D:\ Test \RND\Java\CORBA>java FileClient hello.txt
Expected Output:

You might also like