0% found this document useful (0 votes)
21 views30 pages

Distributed System

DISTRIBUTED_SYSTEM

Uploaded by

Bibin George
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)
21 views30 pages

Distributed System

DISTRIBUTED_SYSTEM

Uploaded by

Bibin George
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/ 30

CET-IILM-AHL

DISTRIBUTED SYSTEM
LABORATORY FILE ECS-701
CS 7B 4th YEAR (1015010077)

SUBMITTED TO: SUBMITTED BY:


Mrs. Rupali Goyal SAMEER GUPTA

INDEX
S.NO DATE CONTENT SIGN

1. Program for simulating Lamport Logical


Clock

2. Program for implementing Vector Clock

3. Program for simulating Distributed Mutual


Exclusion

4. Program for implementing Distributed Chat


Server using TCP Sockets

5. Program for implementing Java RMI


Mechanism

6. Program for simulating Balanced Sliding


Window Protocol

7. Program for implementing CORBA


mechanism by using C++ program at one end
and Java program on the other.
1. Program for simulating Lamport Logical Clock

THEORY:

Inherent Limitations of a Distributed System


Absence of Global clock
•difficult to make temporal order of events
•difficult to collect up-to-date information on the state of the entire system absence of Shared
Memory
•no up-to-date state of the entire system to any individual process as there's no shared memory
•coherent view -- all observations of different processes ( computers ) are made at the same physical
time we can obtain a coherent but partial view of the system or incoherent view of the system
• complete view ( global state ) -- local views ( local states ) + messages in transit difficult to obtain a
coherent global state

Leslie Lamport proposed this scheme to provide ordering of events in a distributed environment
using logical clocks. Because it is impossible to have perfectly synchronized clocks and global time in
a distributed system, it is often necessary to use logical clocks instead

Definitions:
Happened Before Relation (->). This relation captures causal dependencies between events,
That is ,whether or not events have a cause and effect relation.
This relation (->) is defined as follows:
a -> b, if a and b are in the same process and a occurred before b.
a -> b, if a is the event of sending a message and b is the receipt of that message by another
process.
If a -> b and b -> c, then a -> c - that is, the relation has the property of transitivity.
Causally Related Events: If event a -> event b, then a causally affects b.
Concurrent Events: Two distinct events a and b are concurrent (a || b) if (not) a -> b and (not) b
> a. That is, the events have no causal relationship. This is equivalent to b || a.
For any two events a and b in a system, only one of the following is true: a -> b, b -> a, or a || b.
e11 → e12 , e12 → e22e21 → e13 , e14 || e24
Lamport introduced a system of logical clocks in order to make the -> relation possible. It works
like this: Each process Pi in the system has its own clock Ci. Ci can be looked at as a function
that assigns a number, Ci (a) to an event a. This is the timestamp of the event a in process Pi.
These numbers are not in any way related to physical time -- that is why they are called logical
clocks. These are generally implemented using counters, which increase each time an event
occurs. Generally, an event's timestamp is the value of the clock at that time it occurs

Conditions Satisfied by the Logical Clock system:


For any events a and b, if a -> b, then C(a) < C(b). This is true if two conditions are met:
If a occurs before b, then Ci(a) < Ci(b).
If a is a message sent from Pi and b is the recept of that same message in Pj, then Ci(a) < Cj(b).
Implementation Rules Required:
Clock Ci is incremented for each event: Ci := Ci + d (d > 0)
if a is the event of sending a message from one process to another, then the receiver sets its clock
to the max of its current clock and the sender's clock - that is, Cj := max(Cj, tm + d) (d > 0)
Limitation of Lamport's Clocks:
if a → b then C(a) < C(b) but C(a) < C(b) does not necessarily imply a →b

PROGRAM:

#include<stdio.h>
#include<conio.h>
#include<iostream.h>
#include<stdlib.h>
#include<graphics.h>
#include<string.h>
#include<dos.h>
void main(){
int s[4][9],n,m=0;
int i,j,next=0,step=0;
int msg[10][4]={0},totmsg;
char op;
int pi,pj,ei,ej;
clrscr();
cout<<"\nProgram for Lamport Logical Clock";
cout<<"\nEnter Number Of Process ";
cin>>n;
for(i=0;i<n;i++){
cout<<"\nEnter number of STATES of process P"<<i<<" ";
cin>>s[i][8];
for(j=1;j<=s[i][8];j++){
s[i][j]=j;
}
}
do{
cout<<"\nEnter message transit";
cout<<"\nFROM ->\nEnter Process Number P";
cin>>msg[m][0];
cout<<"\nEnter Event Number e";
cin>>msg[m][1];
cout<<"\nTO ->\nEnter Process Number P";
cin>>msg[m][2];
cout<<"\nEnter Event Number e";
cin>>msg[m][3];
cout<<"\n\nPress 'y' to continue";
op=getch();
cout<<op;
m++;
totmsg=m;
}while(op=='y');
m=0;
for (i=0;i<totmsg;i++)
{
pi=msg[i][0];
ei=msg[i][1];
pj=msg[i][2];
ej=msg[i][3];
if(s[pj][ej]< (s[pi][ei]+1)){
s[pj][ej]=s[pi][ei]+1;
for (j=ej+1;j<=s[pj][8];j++){
s[pj][j]=s[pj][j-1]+1;
}
}
}
int gd=DETECT,gm;
initgraph(&gd,&gm,"C:\\TC\\BGI");
outtextxy(200,15,"Program For Lamport Logical Clock");
//drawing process and events
for(i=0;i<n;i++){
char* p1;
itoa(i,p1,10);
outtextxy(5,100+next,"P");
outtextxy(13,100+next,p1);
line(100,100+next,600,100+next);
for(j=1;j<=s[i][8];j++){
char* p2;
itoa(j,p2,10);
outtextxy(100+step,90+next,"e");
outtextxy(110+step,90+next,p2);
//timestamp
char* p3;
itoa(s[i][j]-1,p3,10);
outtextxy(100+step,110+next,"t");
outtextxy(110+step,110+next,p3);
circle(105+step,100+next,5);
step+=50;
}
step=0;
next+=100;
}
delay(2000);
//drawing message transit
for(m=0;m<totmsg;m++){
setlinestyle(SOLID_LINE,1,3);
setcolor(m+4);
line(msg[m][1]*50+50,msg[m][0]*100+100,msg[m][3]*50+50,msg[m][2]*100+100);
if (msg[m][2]>msg[m][0]){
line(msg[m][3]*50+50,msg[m][2]*100+100,msg[m][3]*50+50,msg[m][2]*100+90);
line(msg[m][3]*50+50,msg[m][2]*100+100,msg[m][3]*50+40,msg[m][2]*100+90); }
else{
line(msg[m][3]*50+50,msg[m][2]*100+100,msg[m][3]*50+50,msg[m][2]*100+110);
line(msg[m][3]*50+50,msg[m][2]*100+100,msg[m][3]*50+40,msg[m][2]*100+110);
}
}
getch();
}
2. Program for implementing Vector Clock

THEORY:

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 increments its own logical clock in the vector by one
and then 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).

The vector clocks algorithm was independently developed by Colin Fidge and Friedemann Mattern in
1988.

PROGRAM:

#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]; }

3. Program for simulating Distributed Mutual Exclusion


THEORY:

Distributed mutual exclusion (DME) coordinates software on different computers so that they
Agree upon assigning a resource or section of code to one particular task.

Requirement
• Mutual Exclusion
• Freedom from deadlock
• Eventual entry(freedom from starvation)
• All processes must participate equally.
• Only interested processes participate.

Assumptions
•N nodes randomly request access.
•Messages are not lost or corrupted.
•Message transmissions take a finite, variable, non-zero time.
•Messages arrive in order.
•Transmission time might not be transitive.
•Network is fully connected.

Mutual Exclusion Goals


• Minimize the number of messages sent.
• Grant permission in order of request
• Fault tolerant
• Fair to all systems
• Scalable

PROGRAM:
mutex1.c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *functionC();
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
int counter = 0;
main()
{
int rc1, rc2;
pthread_t thread1, thread2;
/* Create independent threads each of which will execute functionC */
if( (rc1=pthread_create( &thread1, NULL, &functionC, NULL)) )
{
printf("Thread creation failed: %d\n", rc1);
}
if( (rc2=pthread_create( &thread2, NULL, &functionC, NULL)) )
{
printf("Thread creation failed: %d\n", rc2);
}
/* Wait till threads are complete before main continues. Unless we */
/* wait we run the risk of executing an exit which will terminate */
/* the process and all threads before the threads have completed. */
pthread_join( thread1, NULL);
pthread_join( thread2, NULL);
exit(0);
}
void *functionC()
{
pthread_mutex_lock( &mutex1 );
counter++;
printf("Counter value: %d\n",counter);
pthread_mutex_unlock( &mutex1 );
}
Compile: cc -lpthread mutex1.c Run: ./a.out Results:
Counter value: 1 Counter value: 2
join1.c
#include <stdio.h>
#include <pthread.h>
#define NTHREADS 10
void *thread_function(void *);
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
int counter = 0;
main()
{
pthread_t thread_id[NTHREADS];
int i, j;
for(i=0; i < NTHREADS; i++)
{
pthread_create( &thread_id[i], NULL, thread_function, NULL );
}
for(j=0; j < NTHREADS; j++)
{
pthread_join( thread_id[j], NULL);
}
/* Now that all threads are complete I can print the final result. */
/* Without the join I could be printing a value before all the threads */
/* have been completed.*/
printf("Final counter value: %d\n", counter);
}
void *thread_function(void *dummyPtr)
{
printf("Thread number %ld\n", pthread_self());
pthread_mutex_lock( &mutex1 );
counter++;
pthread_mutex_unlock( &mutex1 );
}
Compile:cc-lpthreadjoin1.c Run:./a.out Results:
Thread number 1026
Thread number 2051
Thread number 3076
Thread number 4101
Thread number 5126
Thread number 6151

Thread number 7176


Thread number 8201
Thread number 9226
Thread number 10251
Final counter value: 10
cond1.c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t condition_var = PTHREAD_COND_INITIALIZER;
void *functionCount1();
void *functionCount2();
int count = 0;
#define COUNT_DONE 10
#define COUNT_HALT1 3
#define COUNT_HALT2 6
main()
{
pthread_t thread1, thread2;
pthread_create( &thread1, NULL, &functionCount1, NULL);
pthread_create( &thread2, NULL, &functionCount2, NULL);
pthread_join( thread1, NULL);
pthread_join( thread2, NULL);
printf("Final count: %d\n",count);
exit(0);
}
// Write numbers 1-3 and 8-10 as permitted by functionCount2()
void *functionCount1()
{
for(;;)
{
// Lock mutex and then wait for signal to relase mutex
pthread_mutex_lock( &count_mutex );
// Wait while functionCount2() operates on count
// mutex unlocked if condition varialbe in functionCount2() signaled.
pthread_cond_wait( &condition_var, &count_mutex );
count++;
printf("Counter value functionCount1: %d\n",count);
pthread_mutex_unlock( &count_mutex );
if(count >= COUNT_DONE) return(NULL);
}
}
// Write numbers 4-7
void *functionCount2()
{

for(;;)
{
pthread_mutex_lock( &count_mutex );
if( count < COUNT_HALT1 || count > COUNT_HALT2 )
{
// Condition of if statement has been met.
// Signal to free waiting thread by freeing the mutex.
// Note: functionCount1() is now permitted to modify "count".
pthread_cond_signal( &condition_var );
}
else
{
count++;
printf("Counter value functionCount2: %d\n",count);
}
pthread_mutex_unlock( &count_mutex );
if(count >= COUNT_DONE) return(NULL);
}}
Compile: cc -lpthread cond1.c Run: ./a.out Results:
Counter value functionCount1: 1
Counter value functionCount1: 2
Counter value functionCount1: 3
Counter value functionCount2: 4
Counter value functionCount2: 5
Counter value functionCount2: 6
Counter value functionCount2: 7
Counter value functionCount1: 8
Counter value functionCount1: 9
Counter value functionCount1: 10
Final count: 10
4. Program for implementing Distributed Chat Server using TCP Sockets

THEORY:

A socket is the mechanism that most popular operating systems provide to give programs access to
the network. It allows messages to be sent and received between applications (unrelated processes)
on different networked machines.
The sockets mechanism has been created to be independent of any specific type of network. IP,
however, is by far the most dominant network and the most popular use of sockets. This tutorial
provides an introduction to using sockets over the IP network (IPv4).

This tutorial will not try to cover the entire topic of sockets. There are tutorials on the web that delve
into far greater detail. On-line manual pages will provide you with the latest information on
acceptable parameters and functions. The interface described here is the system call interface
provided by the OS X, Linux, and Solaris operating systems and is generally similar amongst all
Unix/POSIX systems (as well as many other operating systems).

PROGRAM:

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define PORT 5555
#define MAXMSG 512
int
read_from_client (int filedes)
{
char buffer[MAXMSG];
int nbytes;
nbytes = read (filedes, buffer, MAXMSG);
if (nbytes < 0)
{
/* Read error. */
perror ("read");
exit (EXIT_FAILURE);
}
else if (nbytes == 0)
/* End-of-file. */
return -1;
else
{
/* Data read. */
fprintf (stderr, "Server: got message: `%s'\n", buffer);
return 0;
}
}
int
main (void)
{
extern int make_socket (uint16_t port);
int sock;
fd_set active_fd_set, read_fd_set;
int i;
struct sockaddr_in clientname;
size_t size;

/* Create the socket and set it up to accept connections. */


sock = make_socket (PORT);
if (listen (sock, 1) < 0)
{
perror ("listen");
exit (EXIT_FAILURE);
}
/* Initialize the set of active sockets. */
FD_ZERO (&active_fd_set);
FD_SET (sock, &active_fd_set);
while (1)
{
/* Block until input arrives on one or more active sockets. */
read_fd_set = active_fd_set;
if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0)
{
perror ("select");
exit (EXIT_FAILURE);
}
/* Service all the sockets with input pending. */
for (i = 0; i < FD_SETSIZE; ++i)
if (FD_ISSET (i, &read_fd_set))
{
if (i == sock)
{
/* Connection request on original socket. */
int new;
size = sizeof (clientname);
new = accept (sock,
(struct sockaddr *) &clientname,
&size);
if (new < 0)
{
perror ("accept");
exit (EXIT_FAILURE);
}
fprintf (stderr,
"Server: connect from host %s, port %hd.\n",
inet_ntoa (clientname.sin_addr),
ntohs (clientname.sin_port));
FD_SET (new, &active_fd_set);
}
else
{
/* Data arriving on an already-connected socket. */
if (read_from_client (i) < 0) {
close (i);
FD_CLR (i, &active_fd_set);
}}}}}

5. Program for implementing Java RMI Mechanism

THEORY:

The Java Remote Method Invocation (Java RMI) is a Java API that performs the object-oriented
equivalent of remote procedure calls (RPC), with support for direct transfer of serialized Java objects
and distributed garbage collection.
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).
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, whereas the term RMI-IIOP (read: RMI over IIOP) denotes the RMI interface delegating most
of the functionality to the supporting CORBA implementation.

PROGRAM:
Hello.java
import java.rmi.*;
import java.rmi.server.*;
public class Hello extends UnicastRemoteObject implements HelloInterface {
private String message;
public Hello (String msg) throws RemoteException {
message = msg;
}
public String say() throws RemoteException {
return message;
}
}
HelloClient.java
import java.rmi.Naming;
public class HelloClient
{
public static void main (String[] argv) {
try {
HelloInterface hello =(HelloInterface) Naming.lookup ("//192.168.10.201/Hello");
System.out.println (hello.say());
}
catch (Exception e){
System.out.println ("HelloClient exception: " + e);}
}
}
HelloInterface.java
import java.rmi.*;
public interface HelloInterface extends Remote {
public String say() throws RemoteException;
}
HelloServer.java
import java.rmi.Naming;
public class HelloServer
{
public static void main (String[] argv)
{
try {
Naming.rebind ("Hello", new Hello ("Hello,From Roseindia.net pvt ltd!"));
System.out.println ("Server is connected and ready for operation.");
} catch (Exception e) {
System.out.println ("Server not connected: " + e);
}
}}

6. Program for simulating Balanced Sliding Window Protocol

THEORY:

Definitions
•Two processes, p and q, each sending an infinite array of words to theother
•For Process p:inp: An infinite array of words to be sent to process q outp:An infinite array of words
being received from process qInitially for all i, out outp[i] = udefSp:The lowest numbered word that p still
expects to receive from q. At any time, p has already written out outp[0] [through out outp[i]
Required Properties
Safe delivery
•In every reachable configuration of the protocol
outp [0 … sp - 1]=inq[0 … sp - 1] and
outq [0 … sq - 1]=inp[0 … sq - 1]
Eventual delivery
•For every integer k ≥0, a configuration with , sp ≥k and and sq ≥k is eventually reached
The protocol
•The packet, < pack,w, i > transmits the word w = inp[i] to q.
• The processes use constants ip and iq as follows:
-Process p can send the word w=inp[i] (as the packet, <pack, w, i>) onlyafter storing all
the words outp[0] through outp[i – lp], that is, i < sp + lp.
-When p receives < pack,w, i >, retransmission of words from inp[0] through inp[i – lq ]
is no longer necessary.

PROGRAM:
#include <STDIO.H>
#include <iostream.h>
#include <string>
#define THANKS -1
void main()
{
FILE *r_File1;
FILE *w_File2;
int m_framecount;
int frameCount = 0;
long currentP = 0;
long sentChar = 0;
long recvedChar = 0;
char s_name[100];
char d_name[100];
char *sp = s_name;
char *dp = d_name;
int slidingWin;
int frameSize;
int dataSize;
bool isEnd = false;
struct FRAME{
int s_flag;
intsequenceNo;
char data[90];
int n_flag;
};
FRAME frame;
frame.s_flag = 126;//set start flag
frame.n_flag = 126;//set end flag
memset(frame.data, 0, 91);//use 0 to fill full the member array in structure frame.
struct ACK{

int s_flag;
int nextSeq;
int n_flag;
}ack;
//initialize start flag and end flag in structure ack.
ack.s_flag = 126;
ack.n_flag = 126;
ack.nextSeq = NULL;
//ask user to enter file name and size of sliding window.
lable1 : cout <<"Please enter source file's name!"<<endl;
cin >> sp;
cout <<"Please enter destination file's name!"<<endl;
cin >> dp;
lable2: cout <<"Please chose size of sliding window 2--7"<<endl;
cin >> slidingWin;
if((slidingWin >7 )| (slidingWin < 2))
{
cout << "wrong enter"<<endl;
goto lable2;
}
lable3: cout<< "Please enter the size of frame 14--101 Only!" << endl;
cin >>frameSize;
if((frameSize > 101) | (frameSize < 14))
{ cout << "please enter right number!"<< endl;
goto lable3;
}
//use frameSize to decide the size of data array in structor frame.
dataSize = frameSize - 12;
//dynamic generate a frame array with user enter's size of sliding window
FRAME *pf = new FRAME[slidingWin];
int seqNo = 0;
//strat loop for transmission.
while (ack.nextSeq != THANKS)
{
cout << "THE PROCESS ON SENDER SIDER..."<<endl;
//open a source file by read mode.
if((r_File1 = fopen(sp, "rb")) == NULL)

{
cout << "source file could not be opened please check it and re-start!" <<endl;
goto lable1;
}
else
{
cout<<"Opening a file for read...";
cout <<endl;
cout <<endl;
//after open the file, use fseek to resume the last position of a file pointer.
//Then start to read from that position.
fseek(r_File1,currentP,SEEK_SET);
//start loop for create frame array
for (int i = 0; i < slidingWin ; i++)// i is the frame array's index
{
frame.sequenceNo = seqNo;
if ((seqNo >= 7) == true)
{
seqNo = 0;//set sequencce number
}
else
{
seqNo = seqNo +1;
}
//This loop is used to fill the characters read from opened file to char array data which
//is a memeber of structure frame.
//we have to reseve a byte for \0 which is used to identify the end of the data array.
//that means each time we only read datasize -1 characters to the data array.
for (int j = 0; j < dataSize -1; j++)
{ //if it is not end of file read a character from file then save it into data
//field in frame structure.
frame.data[j]= fgetc(r_File1);
sentChar++;//calculate how many characters will be sent.*/
if (frame.data[j]
{
cout<< "There is the end of file"<<endl;
isEnd = true;
//sentChar++;
break;
}
}
if (isEnd == true)
{
pf[i] = frame; //save a frame into frame array.
//frameCount = i;
frameCount++;
m_framecount = i +1;
cout <<endl;
cout << "The squence number is " << pf[i].sequenceNo <<endl;
cout << "The start flag is " << pf[i].s_flag <<endl;
cout << "The Data is---->" << pf[i].data <<endl;
cout << "The end flag is " << pf[i].n_flag <<endl;
cout << "There are " <<frameCount <<" frames has been created!"<<endl;
cout << "frame " << pf[i].sequenceNo <<" has been transported!";
cout<< endl;
fclose(r_File1);
break;
}
pf[i] = frame;//sava current frame to frame buffer.
//display some informaiton of frame buffer.
frameCount++;
m_framecount = i +1;
cout <<endl;
cout << "The squence number is " << pf[i].sequenceNo <<endl;
cout << "The start flag is " << pf[i].s_flag <<endl;
cout << "The Data is---->" << pf[i].data <<endl;
cout << "The end flag is " << pf[i].n_flag <<endl;
cout << "There are total " <<frameCount <<" frames has been created!"<<endl;
//cout << "frame " << pf[i].sequenceNo <<" has been transported!";
cout<< endl;
currentP = ftell(r_File1);//to record the current position of a file pointer
}
fflush(r_File1);//refresh
}

//print out some information.


cout <<endl;
cout <<"Total " << sentChar << " characters have been sent on this session!"<<endl;
cout <<endl;
cout << "waiting for ACK!" <<endl;
cout <<endl;
cout <<endl;
int nextNoRecord = 0;
cout<<"THE PROCESS ON RECEIVER SIDE..."<<endl;
//open a file for write
if((w_File2 = fopen(dp, "ab")) != NULL)
{
cout<<"opening a file for write..."<<endl;
for (int m = 0; m < m_framecount ; m++)
{
for (int n = 0; n < dataSize -1; n++)
{//check whether islast character.
if(pf[m].data[n]
{
ack.nextSeq = THANKS;
//fputc(pf[m].data[n],w_File2);
recvedChar++;
break;
}
//write the character from current frame 's which in t index of data flied.
fputc(pf[m].data[n],w_File2);
recvedChar++;
}
cout << "The string ---->" << pf[m].data <<" written succeed"<<endl;
fflush(w_File2);//refresh
if(ack.nextSeq == THANKS)
{
fclose(w_File2);
break;
}
nextNoRecord= pf[m].sequenceNo;
}

cout <<endl;
cout <<"Total "<<recvedChar << " characters have been received on this session"<<endl;
cout <<endl;
cout << "send acknowledgement!" <<endl;
cout <<endl;
cout <<endl;
if (ack.nextSeq != THANKS)
{
cout<<"CheckACK"<<endl;
if (nextNoRecord
{
ack.nextSeq =0 ;
}
else
{
ack.nextSeq = nextNoRecord +1;
}
cout << "The next expect frame is " << ack.nextSeq <<endl;
}
else
{ cout<<"CheckACK"<<endl;
cout << "The acknowledgement is thanks. The transmission complete..."<<endl;
//delete the frame buffer array .
delete []pf;
}
}
else
{cout << "File could not be opened" << endl;}
cout <<endl;
cout <<endl;
}
/*can be used to check how many bytes in the specified file
numRead = 0;
fseek(r_File1,0,SEEK_END);
numRead = ftell(r_File1);
cout << "There are " << numRead <<" Bytes in the file" << endl;*/
}
7. Program for implementing CORBA mechanism by using C++ program at
one end and Java program on the other.

THEORY:

CORBA, the Common Object Request Broker Architecture, is a powerful tool for distributed
programming.
It is a language-independent standard specified by the Object Management Group (OMG).
Many CORBA implementations, both free and commercial, exist for a wide variety of Languages
(e.g., C, C++, Java, Perl, Python, and Smalltalk). CORBA allows communication between software
written in any programming language running on any operating system on any hardware
architecture. It handles all serialization and de-serialization of objects and
Method parameters so that programmers do not have to worry about Indian issues and other
system incompatibilities.

CORBA is a mechanism in software for normalizing the method-call semantics between


application objects that reside either in the same address space (application) or remote address
space (same host, or remote host on a network). Version 1.0 was released in October 1991.
CORBA uses an interface definition language (IDL) to specify the interfaces that objects will
present to the outside world. CORBA then specifies a mapping from IDL to a specific
implementation language like C++or Java. Standard mappings exist for Ada, C ,C++, Lisp, Ruby,
Smalltalk, Java, COBOL, PL/Iand Python. There are also nonstandard mappings for Perl, Visual
Basic, Erlang, and Tcl implemented by object request brokers(ORBs) written for those languages.
The CORBA specification dictates that there shall be an ORB through which the Application
interacts with other objects. In practice, the application simply initializes the ORB, and accesses
an internal Object Adapter which maintains such issues as reference counting, object (and
reference) instantiation policies, object lifetime policies, etc. The Object Adapter is used to
register instances of the generated code classes. Generated code classes are the result of
compiling the user IDL code, which translates the high-level interface definition into an OS- and
language-specific class base for use by the user application. This step is necessary in order to
enforce the CORBA semantics and provide a clean user process for interfacing with the CORBA
infrastructure. Some IDL language mappings are "more hostile" than others. For example, due to
the very nature of Java, the IDL-Java Mapping is rather straightforward and makes usage of
CORBA very simple in a Java application. The C++ mapping is not trivial, but accounts for all the
features of CORBA (e.g. exception handling). The C mapping is even stranger (since C is not an
object-oriented language), but it does make sense and properly handles the RPC semantics.
A language mapping requires the developer ("user" in this case) to create some IDL code that
represents the interfaces to his objects. Typically, a CORBA implementation comes with a tool
called an IDL compiler which converts the user's IDL code into some language-specific generated
code. A traditional compiler then compiles the generated code to create the linkable-object files
for the application. Illustration of the auto generation of the infrastructure code from an
interface defined using the CORBA IDL
This figure illustrates the high-level paradigm for remote interprocess communications using
CORBA. Issues not addressed here, but that are accounted-for in the CORBA specification
include: data typing, exceptions, network protocol communication timeouts, etc. For example:
Normally the server side has the Portable Object Adapter (POA) that redirects call either to the
local servants or (to balance the load) to the other servers. Also, both server and client parts
often have interceptors that are described below. Issues CORBA (and thus this figure) does not
address, but that all distributed systems must address: object lifetimes, redundancy/fail-over,
naming semantics (beyond a simple name), memory management, dynamic load balancing,
separation of model between display/ data/control semantics, etc.
In addition to providing users with a language and a platform neutral remote procedure call
specification, CORBA defines commonly needed services such as transactions and security,
events, time, and other domain-specific interface models.
Interoperability:
Different objects, written in different programming languages, can interact with each other by
using CORBA. ORB(Object Request Broker) provides common services to objects written in
different languages. For example, Visibroker provides a common name server for C++/Java
Technology CORBA objects. In some cases, two different ORBs may need to interact, such as a
C++; CORBA object that uses the ORBIT ORB; to talk to a Java Technology object that uses the
Java Technology ORB. CORBA objects use IOR (Interoperable Object Reference) to communicate.
ORB makes the IOR transparent to the programmers. In general, for object A to talk to object B,
A uses the IOR of object B. IOR is the object's address that other objects can refer to. CORBA
specification provides detailed information on the fields of the IOR. There are three ways to
obtain the IOR of an object:
1. String to object
You can obtain a string field object reference (Email, disk, file, etc.) and use the string to object
call to convert it into an object reference.
2. Resolve initial references
You can use this call to get IORs to a small set of well known services.
For example, to use the name server in a single ORB environment, you make the following call:
Resolved initial references ("Name Server");
The ORB returns the IOR to the name server.

3. Lookup
You can look up the IOR in the naming service. Once you have the IOR, you can convert it into an
active object reference by using the string to object call and then invoke methods on it. In an
ORB environment that supports binding for multiple languages (e.g. Visibroker and ORBacus
support C++ and the Java Programming Language), the ORB provides an uniform naming service
to objects of all the languages it supports.
The naming service holds information about all the objects in the ORB. In a single ORB
environment, the naming service is transparent.
If you want objects located on two different ORBs to interact and they share a common name
server, you would use the Lookup method. However, if the objects are located on different ORBs,
then the client needs to get the IOR from the server objects.

PROGRAM:
Creating the Server
#include <iostream>
#include "OB/CORBA.h"
#include <OB/Cosnaming.h>
#include "crypt.h"
#include "cryptimpl.h"
using namespace std;
int main(int argc, char** argv)
{
// Declare ORB and servant object
CORBA::ORB_var orb;
CryptographicImpl* CrypImpl = NULL;
try {
// Initialize the ORB.
orb = CORBA::ORB_init(argc, argv);
// Get a reference to the root POA
CORBA::Object_var rootPOAObj =
orb->resolve_initial_references("RootPOA");
// Narrow it to the correct type
PortableServer::POA_var rootPOA =
PortableServer::POA::_narrow(rootPOAObj.in());
// Create POA policies
CORBA::PolicyList policies;
policies.length(1);
policies[0] =
rootPOA->create_thread_policy
(PortableServer::SINGLE_THREAD_MODEL);
// Get the POA manager object
PortableServer::POAManager_var manager = rootPOA->the_POAManager();
// Create a new POA with specified policies
PortableServer::POA_var myPOA = rootPOA->create_POA
("myPOA", manager, policies);
// Free policies
CORBA::ULong len = policies.length();
for (CORBA::ULong i = 0; i < len; i++)
policies[i]->destroy();
// Get a reference to the Naming Service root_context
CORBA::Object_var rootContextObj =
orb->resolve_initial_references("NameService");
// Narrow to the correct type
CosNaming::NamingContext_var nc =
CosNaming::NamingContext::_narrow(rootContextObj.in());
// Create a reference to the servant
CrypImpl = new CryptographicImpl(orb);
// Activate object
PortableServer::ObjectId_var myObjID =
myPOA->activate_object(CrypImpl);
// Get a CORBA reference with the POA through the servant
CORBA::Object_var o = myPOA->servant_to_reference(CrypImpl);
// The reference is converted to a character string
CORBA::String_var s = orb->object_to_string(o);
cout << "The IOR of the object is: " << s.in() << endl;
CosNaming::Name name;
name.length(1);
name[0].id = (const char *) "CryptographicService";
name[0].kind = (const char *) "";
// Bind the object into the name service
nc->rebind(name,o);
// Activate the POA
manager->activate();
cout << "The server is ready.
Awaiting for incoming requests..." << endl;
// Start the ORB
orb->run();
} catch(const CORBA::Exception& e) {
// Handles CORBA exceptions
cerr << e << endl;
}
// Decrement reference count
if (CrypImpl)
CrypImpl->_remove_ref();
// End CORBA
if (!CORBA::is_nil(orb)){
try{
orb->destroy();
cout << "Ending CORBA..." << endl;
} catch (const CORBA::Exception& e)
{
cout << "orb->destroy() failed:" << e << endl;
return 1;
}
}
return 0;
}
►SOURCE CODE
Implementing the Client
#include <iostream>
#include <string>
#include "OB/CORBA.h"
#include "OB/Cosnaming.h"
#include "crypt.h"
using namespace std;

int main(int argc, char** argv)


{
// Declare ORB
CORBA::ORB_var orb;
try {
// Initialize the ORB
orb = CORBA::ORB_init(argc, argv);
// Get a reference to the Naming Service
CORBA::Object_var rootContextObj =
orb->resolve_initial_references("NameService");
CosNaming::NamingContext_var nc =
CosNaming::NamingContext::_narrow(rootContextObj.in());
CosNaming::Name name;
name.length(1);
name[0].id = (const char *) "CryptographicService";
name[0].kind = (const char *) "";
// Invoke the root context to retrieve the object reference
CORBA::Object_var managerObj = nc->resolve(name);
// Narrow the previous object to obtain the correct type
::CaesarAlgorithm_var manager =
::CaesarAlgorithm::_narrow(managerObj.in());
string info_in,exit,dummy;
CORBA::String_var info_out;
::CaesarAlgorithm::charsequence_var inseq;
unsigned long key,shift;
try{
do{
cout << "\nCryptographic service client" << endl;
cout << "----------------------------" << endl;
do{ // Get the cryptographic key
if (cin.fail())
{
cin.clear();
cin >> dummy;
}
cout << "Enter encryption key: ";
cin >> key;
} while (cin.fail());
do{ // Get the shift
if (cin.fail())
{
cin.clear();
cin >> dummy;
}
cout << "Enter a shift: ";
cin >> shift;
} while (cin.fail());
// Used for debug pourposes
//key = 9876453;
//shift = 938372;

getline(cin,dummy); // Get the text to encrypt


cout << "Enter a plain text to encrypt: ";
getline(cin,info_in);
// Invoke first remote method
inseq = manager->encrypt
(info_in.c_str(),key,shift);
cout << "------------------------------------------"
<< endl;
cout << "Encrypted text is: "
<< inseq->get_buffer() << endl;
// Invoke second remote method
info_out = manager->decrypt(inseq.in(),key,shift);
cout << "Decrypted text is: "
<< info_out.in() << endl;
cout << "-------------------------------------------"
<< endl;
cout << "Exit? (y/n): ";
cin >> exit;
} while (exit!="y");
// Shutdown server message
manager->shutdown();
} catch(const std::exception& std_e){
cerr << std_e.what() << endl;
}
}catch(const CORBA::Exception& e) {
// Handles CORBA exceptions
cerr << e << endl;
}
// End CORBA
if (!CORBA::is_nil(orb)){
try{
orb->destroy();
cout << "Ending CORBA..." << endl;
} catch(const CORBA::Exception& e)
{
cout << "orb->destroy failed:" << e << endl;
return 1;
}
}
return 0;
}

You might also like