os lab manual
TRANSCRIPT
Network-OS Lab Manual
LINUX - THE OS
Linux is a Unix-like computer operating system. Linux is one of the most prominent
examples of free software and open source development; its underlying source code can be
modified, used, and redistributed by anyone, freely.
The Linux kernel was first released to the public on 17 September 1991, for the Intel
x86 PC architecture. The kernel was augmented with system utilities and libraries from the
GNU project to create a usable operating system, which later led to the alternate term
GNU/Linux.Linux is now packaged for different uses in Linux distributions, which contain
the kernel along with a variety of other software packages tailored to requirements.
Predominantly known for its use in servers, Linux has gained the support of
corporations such as IBM, Sun Microsystems, Hewlett-Packard, and Novell, and is used as
an operating system for a wide variety of computer hardware, including desktop computers,
supercomputers, and embedded devices such as mobile phones and routers.
The Unix operating system was conceived and implemented in the 1960s and first
released in 1970. Its wide availability and portability meant that it was widely adopted,
copied and modified by academic institutions and businesses, with its design being
influential on authors of other systems.
A 2001 study of Red Hat Linux 7.1 found that this distribution contained 30 million
source lines of code. Using the Constructive Cost Model, the study estimated that this
distribution required about eight thousand man-years of development time. According to the
study, if all this software had been developed by conventional proprietary means, it would
have cost about 1.08 billion dollars (year 2000 U.S. dollars) to develop in the United States.
Most of the code (71%) was written in the C programming language, but many other
languages were used, including C++, Lisp, assembly language, Perl, Fortran, Python and
Department Of Computer Science BM II College Of Engineering, Sasthamcotta1
Network-OS Lab Manual
various shell scripting languages. Slightly over half of all lines of code were licensed under
the GPL. The Linux kernel itself was 2.4 million lines of code, or 8% of the total
Programming on Linux
Most Linux distributions support dozens of programming languages. Core system
software such as libraries and basic utilities are usually written in C. Enterprise software is
often written in C, C++, Java, Perl, Ruby, or Python. The most common collection of utilities
for building both Linux applications and operating system programs is found within the GNU
toolchain, which includes the GNU Compiler Collection (GCC) and the GNU build system.
Amongst others, GCC provides compilers for C, C++, Java, and Fortran. The Linux kernel
itself is written to be compiled with GCC.
Most also include support for Perl, Ruby, Python and other dynamic languages.
Examples of languages that are less common, but still well-supported, are C# via the Mono
project, and Scheme. A number of Java Virtual Machines and development kits run on
Linux, including the original Sun Microsystems JVM (HotSpot), and IBM's J2SE RE, as well
as many open-source projects like Kaffe. The two main frameworks for developing graphical
applications are those of GNOME and KDE. These projects are based on the GTK+ and Qt
widget toolkits, respectively, which can also be used independently of the larger framework.
Both support a wide variety of languages. There are a number of Integrated development
environments available including Anjuta, Eclipse, KDevelop, MonoDevelop, NetBeans, and
Omnis Studio while the traditional editors Vim and Emacs remain popular.
Although free and open source compilers and tools are widely used under Linux,
there are also proprietary solutions available from a range of companies, including the Intel
C++ Compiler, PathScale, Micro Focus COBOL, Franz Inc, and the Portland Group.
We use here, vi editor for all entering and editing purposes. The commands used
in vi editors are….
Department Of Computer Science BM II College Of Engineering, Sasthamcotta2
Network-OS Lab Manual
To Start
To use vi on a file type in vi filename. If the file named filename exist, then it
wthe file will be displayed,otherwise an empty file and screen are created into which you
may enter the text.
vi filename –edit filename startng at line 1
vi –r filename recover filename that was being edited when system crashed.
To Exit vi
Usually the new or modified filename is saved when you leave vi. However it also
possible to quit without saving the file.
:x<return> - quit vi, writing out modified file named in original invocation.
:wq<return> - quit vi, writing out the modified file to file named in original invocation.
:q< return> -quit(or exit) vi.
: q!<return> -quit vi even though latest cvhanges have not been saved for this vi call.
Moving the cursor
The symbol ^ shown below , before a letter means that the <ctrl>key should be
held down while the letter is pressed.
J or ,return>{or down arrow] - move the cursor down one line.
K[or up-arrow] - move the cursor up one line.
H or <Backspace>[or left arrow] –move cursor left one character.
L or <space>[or right arrow] -move cursor right one character.
0(zero) -move cursor to start of the current line.
$ -move cursor to end of current line.
w –move cursor to the beginning of the next word.
B -move the cursor back to beginning of the preceeding word.
:0<return>or 1G -move the cursor to first line in file.
:n<return> or nG -move the cursor to line n.
:$<return> or G -move cursor to last of the line.
Department Of Computer Science BM II College Of Engineering, Sasthamcotta3
Network-OS Lab Manual
Screen Manipulation
The following commands allow the vi editor screen(or window) to move up or
down several lines and to be refreshed.
^f -move forward one screen.
^b –move backward one screen.
^d –move down(forward) one half screen.
^u –move up(back) one half screen.
^l – redraws the screen removing the deleted lines.
Inserting or Adding Text
The following commands allow you to insert and add text. Each of these
commands puts the vi editor into insert mode; thus the >Esc> key must be pressed to
terminate the entry of thetext and to put the vi editor back into command mode.
i - insert text before cursor, until<Esc> hit.
I - insert text at begginning of current line, until<Esc> hit.
a – append text after cursor, until <Esc> hit.
A –append text to end of the current line,until<Esc> hit.
o –open and put text in a new line below current line, until<Esc>hit.
O –open and put text in anew line above current line, until <Esc> hit.
Deleting Text
The following commands allow you to delete text.
x- delete single character under cursor.
Nx –delete N characters, starting with character under cursor.
dw – delete the single word beginning with the character under cursor.
dNw – delete N words beginning with the character under cursor.
D – delete the remainder of line,starting with current cursor position.
dd –delete entire curent line.
Ndd or dNd –delete N lines beginning with the curent line.
Department Of Computer Science BM II College Of Engineering, Sasthamcotta4
Network-OS Lab Manual
Cutting and Pasting Text
The following commands allow you to copy and paste text.
yy - copy(yank,cut)the curent line into buffer.
Nyy or yNy –copy(yank,cut) the next N lines, including the curent line, into the buffer.
p –put(paste) the line(s) in the buffer into the text after the current line.
Searching Text
A common occurences in text editing is to replace one word or phrase by
another.To locate instances of particular sets of characters(or strings), use the following
commands.
/string –search forward for occurrence of string in text.
?string –search back ward for occurences of string in text.
n –move to next occurrence of search string.
N –move the next occurence of search string in opposite direction.
Saving and Reading Files
These commands permit you to input and output files other than the named file
with which you are currently working.
:r filename<return> -read file named filename and insert after current line.
:w<return> -write current contents to file named in original vi call.
:w newfile<return> -write current contents to a new file bnamed newfile.
:12,35w smallfile<return> -write the contents of the lines numbered 12 through 35 to a new
file named smallfile.
:w! prevfile<return> - write curent contents over a pre-existing file named prevfile.
GCC Commands
gcc programname.c –This compile and link the program and a.out file is created . This can be
executed by ./a.out .
gcc –o outputprogramname programname.c- This compile and link the programand a.out file
is created. This can be executed by outputprogramname.
gcc –o outputprogramname programname.c-lpthread – To compile with threads
Department Of Computer Science BM II College Of Engineering, Sasthamcotta5
Network-OS Lab Manual
THREAD
Theory
Multiple strands of execution in a single program are called threads or thread is a
sequences of control within a process.Thread proces include thread creation, termination,
synchronization (joins,blocking), scheduling and process interaction.All threads within a
process share the same addresss space.
A thread in computer science is short for a thread of execution. Threads are a way
for a program to fork (or split) itself into two or more simultaneously (or pseudo-
simultaneously) running tasks. Threads and processes differ from one operating system to
another, but in general, the way that a thread is created and shares its resources is different
from the way a process does.
Multiple threads can be executed in parallel on many computer systems. This
multithreading generally occurs by time slicing, wherein a single processor switches between
different threads, in which case the processing is not literally simultaneous, for the single
processor is only really doing one thing at a time. This switching can happen so fast as to
give the illusion of simultaneity to an end user.
Threads are distinguished from traditional multi-tasking operating system processes in
that processes are typically independent, carry considerable state information, have separate
address spaces, and interact only through system-provided inter-process communication
mechanisms. Multiple threads, on the other hand, typically share the state information of a
single process, and share memory and other resources directly. Context switching between
threads in the same process is typically faster than context switching between processes.
Systems like Windows NT and OS/2 are said to have "cheap" threads and "expensive"
processes; in other operating systems there is not so great a difference.
Department Of Computer Science BM II College Of Engineering, Sasthamcotta6
Network-OS Lab Manual
Thread Basics
Thread operations include thread creation, termination, synchronization
(joins,blocking), scheduling, data management and process interaction.
A thread does not maintain a list of created threads, nor does it know the thread that
created it.
All threads within a process share the same address space.
Threads in the same process share:
o Process instructions
o Most data
o open files (descriptors)
o signals and signal handlers
o current working directory
o User and group id
Each thread has a unique:
o Thread ID
o set of registers, stack pointer
o stack for local variables, return addresses
o signal mask
o priority
o Return value: errno
pthread functions return "0" if OK.
Thread Creation
Function call : pthread_create
int pthread_create(pthread_t*thread,pthread_attr_t*attr,void *(*start_routine)
(void*),void *arg);
Arguments
->thread - returns the thread id.(unsigned long int defined in bits/pthreadtypes.h)
Department Of Computer Science BM II College Of Engineering, Sasthamcotta7
Network-OS Lab Manual
->attr-Set to NULL if default thread attributes are used.(else define members of the struct
pthread_attr_t defined in bits/pthreadtypes.h). Attributes include:
detached state(joinable? Default: PTHREAD_CREATE_JOINABLE.Other
option:PTHREAD_CREATE_DETACHED)
schedulingpolicy(realtime?
PTHREAD_INHERIT_SCHED,PTHREAD_EXPLICIT_SCHED,SCHED_OTHER)
scheduling parameter
inheritsched attribute(Default:PTHREAD_EXPLICIT_SCHED,inherit from parent
thread:PTHREAD_INHERIT_SCHED)
scope(Kernelthreads:PTHREAD_SCOPE_SYSTEM user threads
PTHREAD_SCOPE_PROCESS, pick one or the other not both)
guard size
stack address
stack size(default minimum PTHREAD_STACK_SIZE set in pthread.h)
->void *(start_routine)-pointer to the function to be threaded.Function has a single
argument:pointer to void.
->*arg-pointer to argument of function. To pass multiple arguments,sent a pointer to the
structure.
Termination Of Thread
Function call: pthread_exit
void pthread_exit(void *retval);
Arguments
retval – return value of the thread.
This routine kills the thread.The pthread _exit never returns. If the thread is not detached the
thread id and return value may be examined from another thread by using pthread_join.
Thread Synchronization
The thread libraries provide three synchronization mechanisms
mutexes – Mutual exclusion lock: Block access to variable by other threads. This
enforces exclusive access by thread to a variable or set of variables.
Department Of Computer Science BM II College Of Engineering, Sasthamcotta8
Network-OS Lab Manual
joins–Make athread wait till others are complete(terminated).
conditions variables- data type pthread_cond_t.
Benefits of Threads vs Processes
If implemented correctly then threads have some advantages of (multi) processes, They take:
Less time to create a new thread than a process, because the newly created thread uses
the current process address space.
Less time to terminate a thread than a process.
Less time to switch between two threads within the same process, partly because the
newly created thread uses the current process address space.
Less communication overheads -- communicating between the threads of one process
is simple because the threads share everything: address space, in particular. So, data
produced by one thread is immediately available to all the other threads.
POSIX Threads is a POSIX standard for threads. The standard defines an API for
creating and manipulating threads.
Libraries implementing the POSIX Threads standard are often named Pthreads.
Pthreads are most commonly used on POSIX systems such as Linux and Unix,
Algorithm
1. Start.
2. Provide function prototype and definition for the function that is used as thread.
3. Declare variables for storing the thread id and thread attributes.
4. Initialise the thread attributes.
5. Create the thread.
6. Call the thread for execution.
7. Wait for the thread to execute.
8. Stop.
Department Of Computer Science BM II College Of Engineering, Sasthamcotta9
Network-OS Lab Manual
Program
/*Program for the creation of simple thread created in a non detached manner.
* This program illustrates the manner in which a thread can be created from within
the main() function.
* This program creates a thread called 'add' which accepts two integer values from
the user and prints the sum of it.
* NOTE:->This program should be compiled using the command 'cc
simplethread.c -lpthread' and executed using './a.out'.
*/
//inculsion part
#include<stdio.h>
#include<pthread.h>
void* add(void*); //prototype of the thread function.
int main() //main function (return type should be int in linux).
{
int error; //variable to check error (optional)
pthread_t thread_id; //variable to store thread id.
pthread_attr_t thread_attribute; //variable to store properties of thread.
pthread_attr_init(&thread_attribute); //function call for setting the default properties.
error=pthread_create(&thread_id,&thread_attribute,add,NULL); //function for thread
creation.
//error checking (optional)
if(error!=0)
{
printf("\nError in thread creation.\n");
exit(0);
}
error=pthread_join(thread_id,NULL); //function for thread calling.
//error checking (optional)
if(error!=0)
Department Of Computer Science BM II College Of Engineering, Sasthamcotta10
Network-OS Lab Manual
{ printf("\nError in thread joining.\n");
exit(0);
}
} //function definition for the thread function.
void * add(void *args)
{ int a,b;
printf("\nEnter the first number.\n");
scanf("%d",&a);
printf("\nEnter the second number.\n");
scanf("%d",&b);
printf("\nThe sum is:\t%d\n",a+b);
}
Output
MULTIPLE THREAD
Department Of Computer Science BM II College Of Engineering, Sasthamcotta11
Network-OS Lab Manual
Algorithm
1. Start.
2. Provide function prototype and definition for the function that has to be used as thread.
3. Declare the variables for storing the thread id and thread attributes as required
depending on the no: of threads to be created.
4. Initialize the thread attribute variables to their default values.
5. Set detach property of the thread.
6. Create the threads as required.
7. Wait for the thread to execute.
8. Stop.
Program
//Inculsion part.
#include<stdio.h>#include<pthread.h>
//function prototype.void * add(void *);
//Variable to count the executed thread.int end;
//main function.int main(){ pthread_t tid1,tid2; pthread_attr_t attribute;
pthread_attr_init(&attribute); //function to set detach property of the thread.
pthread_attr_setdetachstate(&attribute,PTHREAD_CREATE_DETACHED);
pthread_create(&tid1,&attribute,add,(void *)1); pthread_create(&tid2,&attribute,add,(void*)2);
//to wait for the thread to finish execution. while(end<2) { }
Department Of Computer Science BM II College Of Engineering, Sasthamcotta12
Network-OS Lab Manual
}
//function prototype for the thread function.void * add(void * args){ int a,b; printf("\nEntered into %d thread\n",args); printf("\nEnter the first number for thread %d\n",args); scanf("%d",&a);
printf("\nEnter the second number for thread %d\n",args); scanf("%d",&b);
printf("The sum computed by thread %d:\t%d\n",args,a+b); end++;}
Output
DYNAMIC MULTITHREAD CREATION
Department Of Computer Science BM II College Of Engineering, Sasthamcotta13
Network-OS Lab Manual
Algorithm
1. Start.
2. Provide the function prototype and definition for the function that
has to be used as thread.
3. Declare variables to store the thread id and thread attributes.
4. Accept the no. of threads from the user.
5. Create the threads by suitably initialising the thread variables.
6. Wait until the threads execute.
7. Stop.
Program
/*Program to describe dynamic multiple thread creation and passing arguments to it.
* This program illustrates the steps involved in creating multiple threads dynamically.
* This program accepts the number of threads from the user and creates it at run time.
* The procedure is similar to that we used to create multiple threads.
NOTE:->This module can be compiled using the command 'cc dynamic multithread creation.c -lpthread' and executed using './a.out'
//inculsion.#include<stdio.h>#include<pthread.h>
//function prototype.void * thread_function(void *args[]);
//variable to know the end of threads execution.int end;int main(){ int i,count,j;
Department Of Computer Science BM II College Of Engineering, Sasthamcotta14
Network-OS Lab Manual
int args[2];
pthread_attr_t attribute; pthread_t tid;
pthread_attr_init(&attribute); pthread_attr_setdetachstate(&attribute,PTHREAD_CREATE_DETACHED);
//for accepting the number of threads to be created. printf("\nEnter the number of threads.\n"); scanf("%d",&count); for(i=0,j=count;i<count;i++,j--) {
//inserting the arguments for the thread args[0]=i+1; args[1]=j;
printf("\n\t\tCreating thread %d.\n",i+1);
pthread_create(&tid,&attribute,(void *)thread_function,(void *)args); printf("\n\t\tCreated thread %d\n",i+1); sleep(1); }
//waiting for the thread execution. while(end!=count) { }}
//function definition.void * thread_function(void *args[]){ int a,b;
a=(int)args[0]; b=(int)args[1]; printf("\n\t\tEntered into %d thread.\n",a);
printf("\nFirst value obtained from main function:\t%d\n",a); printf("\nSecond value obtained from main function:\t%d\n",b); end++;}
Department Of Computer Science BM II College Of Engineering, Sasthamcotta15
Network-OS Lab Manual
Output
SEMAPHORE
Department Of Computer Science BM II College Of Engineering, Sasthamcotta16
Network-OS Lab Manual
Theory
Semaphores are a programming construct designed by E. W. Dijkstra in the late
1960s. Dijkstra's model was the operation of railroads: consider a stretch of railroad in which
there is a single track over which only one train at a time is allowed. Guarding this track is a
semaphore. A train must wait before entering the single track until the semaphore is in a state
that permits travel. When the train enters the track, the semaphore changes state to prevent
other trains from entering the track. A train that is leaving this section of track must again
change the state of the semaphore to allow another train to enter. In the computer version, a
semaphore appears to be a simple integer. A process (or a thread) waits for permission to
proceed by waiting for the integer to become 0. The signal if it proceeds signals that this by
performing incrementing the integer by 1. When it is finished, the process changes the
semaphore's value by subtracting one from it.
Semaphore is a variable that can take only the values 0 and 1, binary semaphore. This
is the most common form. Semaphore that can take many positive values are called general
semaphores.
The definition of P and V are surprisingly simple. Suppose we have semaphore
variable sv. The two operations are defined as follows:
P(sv) – If sv is greater than zero, decrement sv, if sv is zero, suspend execution of this
process.
V(sv) – If some other process has been suspend waiting for sv, make it resume execution. If
no process is suspended waiting for sv, Increment sv.
Semaphores let processes query or alter status information. They are often used to
monitor and control the availability of system resources such as shared memory segments.
POSIX semaphores are much lighter weight than are System V semaphores. A
POSIX semaphore structure defines a single semaphore, not an array of up to twenty five
semaphores. The POSIX semaphore functions are:
sem_open() -- Connects to, and optionally creates, a named semaphore
Department Of Computer Science BM II College Of Engineering, Sasthamcotta17
Network-OS Lab Manual
sem_init() -- Initializes a semaphore structure (internal to the calling program, so not a
named semaphore).
sem_close() -- Ends the connection to an open semaphore.
sem_unlink() -- Ends the connection to an open semaphore and causes the semaphore to be
removed when the last process closes it.
sem_destroy() -- Initializes a semaphore structure (internal to the calling program, so not a
named semaphore).
sem_getvalue() -- Copies the value of the semaphore into the specified integer.
sem_wait(), sem_trywait() -- Blocks while the semaphore is held by other processes or
returns an error if the semaphore is held by another process.
sem_post() -- Increments the count of the semaphore.
All POSIX semaphore functions and types are prototyped or defined in semaphore.h.
To define a semaphore object, use
sem_t sem_name;
To initialize a semaphore, use sem_init():
int sem_init(sem_t *sem, int pshared, unsigned int value);
sem points to a semaphore object to initialize
pshared is a flag indicating whether or not the semaphore should be shared with
fork()ed processes. LinuxThreads does not currently support shared semaphores
value is an initial value to set the semaphore to
Example of use:
sem_init(&sem_name, 0, 10);
Department Of Computer Science BM II College Of Engineering, Sasthamcotta18
Network-OS Lab Manual
To wait on a semaphore, use sem_wait:
int sem_wait(sem_t *sem);
Example of use:
sem_wait(&sem_name);
If the value of the semaphore is negative, the calling process blocks; one of the
blocked processes wakes up when another process calls sem_post.
To increment the value of a semaphore, use sem_post:
int sem_post(sem_t *sem);
Example of use:
sem_post(&sem_name);
It increments the value of the semaphore and wakes up a blocked process waiting on
the semaphore, if any.
To find out the value of a semaphore, use
int sem_getvalue(sem_t *sem, int *valp);
gets the current value of sem and places it in the location pointed to by valp
Example of use:
int value;
sem_getvalue(&sem_name, &value);
printf("The value of the semaphors is %d\n", value);
To destroy a semaphore, use
int sem_destroy(sem_t *sem);
Department Of Computer Science BM II College Of Engineering, Sasthamcotta19
Network-OS Lab Manual
destroys the semaphore; no threads should be waiting on the semaphore if its
destruction is to succeed.
Example of use:
sem_destroy(&sem_name);
Using semaphores - a short example
Consider the problem we had before and now let us use semaphores: Declare the semaphore global (outside of any funcion):
sem_t mutex;
Initialize the semaphore in the main function: sem_init(&mutex, 0, 1);
Thread 1 Thread 2 data
sem_wait (&mutex); --- 0
--- sem_wait (&mutex); 0
a = data; /* blocked */ 0
a = a+1; /* blocked */ 0
data = a; /* blocked */ 1
sem_post (&mutex); /* blocked */ 1
/* blocked */ b = data; 1
/* blocked */ b = b + 1; 1
/* blocked */ data = b; 2
/* blocked */ sem_post (&mutex); 2
[data is fine. The data race is gone.]
The basic operation of these functions is essence the same as described above, except
note there are more specialised functions, here.
Program
/* Program to demonstrate the usage of semaphore variable in controlling the access to specific resources.
Department Of Computer Science BM II College Of Engineering, Sasthamcotta20
Network-OS Lab Manual
* This program contains two functions which display their own messages.
* The display is suitably controlled by the use of semaphore variable.
* It is a program in which a semaphore variable is shared between the main function and a thread function.
* This module can be compiled using 'cc semaphore1.c -lpthread' and executed './a.out'
//inculsion part. #include<stdio.h>#include<pthread.h>#include<semaphore.h>
//function prototype for the thread function.void * display_function();
//global semaphore variable to be shared.sem_t sem_var;
int main(){ pthread_t tid; pthread_attr_t attr; int i;//initialising the semaphore variable with an initial value 0 (third arguement.) sem_init(&sem_var,0,0);
pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
pthread_create(&tid,&attr,display_function,NULL);
for(i=0;i<5;i++) { printf("\n Displaying from the main function:\t%d\n",i+1);
//waiting for the resources. sem_wait(&sem_var); }
//destroying the semaphore variable. sem_destroy(&sem_var);}
void * display_function()
Department Of Computer Science BM II College Of Engineering, Sasthamcotta21
Network-OS Lab Manual
{ int i; for(i=0;i<5;i++) { printf("\n***** Displaying from the thread function.:\t%d\n",i+1);
//releasing resources. sem_post(&sem_var); sleep(1); }}
Output
SERIALISABILITY PROBLEM. (By using Semaphore Variable)
Program
Department Of Computer Science BM II College Of Engineering, Sasthamcotta22
Network-OS Lab Manual
* This program uses a variable 'data' whose value is used by two thread function.
* But the condition is that when a function uses it no other function should use it.
* This problem is tackled by definig two thread function and suitably making them access
it by the use of semaphore variable.
* This module can be compiled using 'cc semaphore2.c -lpthread' and executed './a.out'
//inculsion part.#include<stdio.h>#include<pthread.h>#include<semaphore.h>
//prototype for thread functions.void * thread_function1();void * thread_function2();
//global variables.int data=0,end=0;
//global semaphore variables.sem_t sem_var;
int main(){ pthread_t t1,t2; pthread_attr_t attr;
pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
sem_init(&sem_var,0,1);
pthread_create(&t1,&attr,thread_function1,NULL); pthread_create(&t2,&attr,thread_function2,NULL);
while(end!=2) { }
printf("\n\t****** The value of DATA is:\t%d ******\n",data);}
//definition of first thread function.void * thread_function1(){ int a;
printf("\nEntered into thread function:1\n");
Department Of Computer Science BM II College Of Engineering, Sasthamcotta23
Network-OS Lab Manual
printf("\nThread function:1 waiting to gain access\n");
sleep(1); sem_wait(&sem_var); printf("\nAccess gained by thread function:1\n");
printf("\nThread function:1 using the value of 'DATA' \n");
a=data; a=a+1; data=a;
sem_post(&sem_var); printf("\nResources released by thread function:1\n"); end++;}
//definition of second thread function.void * thread_function2(){ int b;
printf("\nEntered into thread function:2\n"); printf("\nThread function:2 waiting to gain access\n");
sleep(1); sem_wait(&sem_var); printf("\nAccess gained by thread function:2\n"); printf("\nThread function:2 using the value of 'DATA' \n"); b=data; b=b+1; data=b;
sem_post(&sem_var); printf("\nResources released by thread function:2\n"); end++;}
Output
Department Of Computer Science BM II College Of Engineering, Sasthamcotta24
Network-OS Lab Manual
DINING PHILOSOPHER’S PROBLEM
Department Of Computer Science BM II College Of Engineering, Sasthamcotta25
Network-OS Lab Manual
The problem
The dining philosophers problem is summarized as five philosophers sitting at a table
doing one of two things - eating or thinking. While eating, they are not thinking, and while
thinking, they are not eating. The five philosophers sit at a circular table with a large bowl of
spaghetti in the center. A fork is placed in between each philosopher, and as such, each
philosopher has one fork to his or her left and one fork to his or her right. As spaghetti is
difficult to serve and eat with a single fork, it must be assumed that in order for a philosopher
to eat, the philosopher must have two forks. In the case of the dining philosopher, the
philosopher can only use the fork on his or her left or right.
Illustration of the dining philosophers problem
In some cases, the dining philosophers problem is explained using rice and chopsticks
as opposed to spaghetti and forks, as it is generally easier to understand that two chopsticks
are required, whereas one could arguably eat spaghetti using a single fork, or using a fork and
a spoon. In either case, only one instrument (fork or chopstick) can be picked up at a time,
and the philosopher must have two instruments in order to eat.
Department Of Computer Science BM II College Of Engineering, Sasthamcotta26
Network-OS Lab Manual
The philosophers never speak to each other, which creates a dangerous possibility of
deadlock in which every philosopher holds a left fork and waits perpetually for a right fork
(or vice versa).
Originally used as a means of illustrating the problem of deadlock, this system
reaches deadlock when there is a 'cycle of ungranted requests'. In this case philosopher P1
waits for the fork grabbed by philosopher P2 who is waiting for the fork of philosopher P3
and so forth, making a circular chain.
Starvation (and the pun was intended in the original problem description) might also
occur independently of deadlock if a philosopher is unable to acquire both forks due to a
timing issue. For example there might be a rule that the philosophers put down a fork after
waiting five minutes for the other fork to become available and wait a further five minutes
before making their next attempt. This scheme eliminates the possibility of deadlock (the
system can always advance to a different state) but still suffers from the problem of livelock.
If all five philosophers appear in the dining room at exactly the same time and each picks up
their left fork at the same time the philosophers will wait five minutes until they all put their
forks down and then wait a further five minutes before they all pick them up again.
The lack of available forks is an analogy to the locking of shared resources in real
computer programming, a situation known as concurrency. Locking a resource is a common
technique to ensure the resource is accessed by only one program or chunk of code at a time.
When the resource the program is interested in is already locked by another one, the program
waits until it is unlocked. When several programs are involved in locking resources, deadlock
might happen, depending on the circumstances. For example, one program needs two files to
Department Of Computer Science BM II College Of Engineering, Sasthamcotta27
Network-OS Lab Manual
process. When two such programs lock one file each, both programs wait for the other one to
unlock the other file, which will never happen.
Algorithm
* The algorithm for the process is..........
1.Start.
2.Initialise the thread variables as required.
3.Create the threads representing philosophers.
4.Wait until the threads finishes execution.
5.Stop.
The algorithm for the philosopher is as..........
1.Start.
2.Wait for the left fork/spoon.
3.Wait for the right fork/spoon.
4.Start eating.
5 Release the left fork/spoon.
6.Release the right fork/spoon.
7.Stop.
Program
/* Program to implement the solution to dinning philosophers' problem.
* This program uses five thread functions as five philosophers.
* The spoons or forks are represented with five semaphore variables.
* To use shared memory just include the code after the sem_wait() in each thread.
* To compile use 'cc diningphilosopher.c -lpthread'.
* To run './a.out'.
Department Of Computer Science BM II College Of Engineering, Sasthamcotta28
Network-OS Lab Manual
//inculsion#include<stdio.h>#include<pthread.h>#include<semaphore.h>
//macro definition#define cls() printf("\033[H\033[J")#define EATINGTIME 1
//function prototype for the thread function.void * philosopher1();void * philosopher2();void * philosopher3();void * philosopher4();void * philosopher5();
//global decalration of semaphore variables.sem_t sem15,sem12,sem23,sem34,sem45;
//global variable to control the execution of main.int end=0;
int main(){ char a[2];
pthread_t t1,t2,t3,t4,t5; pthread_attr_t at1;
pthread_attr_init(&at1); pthread_attr_setdetachstate(&at1,PTHREAD_CREATE_DETACHED);
sem_init(&sem15,0,1); sem_init(&sem12,0,1); sem_init(&sem23,0,1); sem_init(&sem34,0,1); sem_init(&sem45,0,1);
cls(); printf("\n\n\n\n\n\n"); printf("_____________________________________________________________________________________");
printf("\n\n\n\t\t\tDINNING PHILOSOPHER PROBLEM."); printf("\n\t\t\t____________________________");
printf("\n\n\t\tNO. OF PHILOSOPHERS :5");printf("\n\n\t\tNO. OF FORKS(SPOONS):5\n\n"); printf("_____________________________________________________________________________________");
Department Of Computer Science BM II College Of Engineering, Sasthamcotta29
Network-OS Lab Manual
printf("\n\n\n\t\tPRESS ENTER TO CONTINUE....................."); fgets(a,2,stdin);
cls(); pthread_create(&t1,&at1,philosopher1,NULL); pthread_create(&t2,&at1,philosopher2,NULL); pthread_create(&t3,&at1,philosopher3,NULL); pthread_create(&t4,&at1,philosopher4,NULL); pthread_create(&t5,&at1,philosopher5,NULL);
while(end!=5) { }}
//definition of philosopher1.void * philosopher1(){ int i=0;
printf("\n\t\tPHILOSOPHER-1 THINKING.\n");
while(i<EATINGTIME) { sleep(1);
//waiting to acquire the forks. sem_wait(&sem15); sem_wait(&sem12);
printf("\n\t\t\t* PHILOSOPHER-1 EATING.*\n");
sleep(1);//releasing the forks
sem_post(&sem15); sem_post(&sem12);
printf("\n\t\tPHILOSOPHER-1 THINKING.\n");
i++; } end++;}
//philosopher2.void * philosopher2(){
Department Of Computer Science BM II College Of Engineering, Sasthamcotta30
Network-OS Lab Manual
int i=0;
printf("\n\t\tPHILOSOPHER-2 THINKING.\n");
while(i<EATINGTIME) { sleep(1);
sem_wait(&sem12); sem_wait(&sem23);
printf("\n\t\t\t* PHILOSOPHER-2 EATING.*\n");
sleep(1);
sem_post(&sem12); sem_post(&sem23);
printf("\n\t\tPHILOSOPHER-2 THINKING.\n");
i++; } end++;}
//philosopher 3void * philosopher3(){ int i=0;
printf("\n\t\tPHILOSOPHER-3 THINKING.\n");
while(i<EATINGTIME) { sleep(1);
sem_wait(&sem23); sem_wait(&sem34);
printf("\n\t\t\t* PHILOSOPHER-3 EATING.*\n");
sleep(1);
sem_post(&sem23); sem_post(&sem34);
Department Of Computer Science BM II College Of Engineering, Sasthamcotta31
Network-OS Lab Manual
printf("\n\t\tPHILOSOPHER-3 THINKING.\n");
i++; } end++;}
//philosopher 4.void * philosopher4(){ int i=0;
printf("\n\t\tPHILOSOPHER-4 THINKING.\n");
while(i<EATINGTIME) { sleep(1);
sem_wait(&sem34); sem_wait(&sem45);
printf("\n\t\t\t* PHILOSOPHER-4 EATING.*\n");
sleep(1);
sem_post(&sem34); sem_post(&sem45);
printf("\n\t\tPHILOSOPHER-4 THINKING.\n");
i++; } end++;}
//philosopher 5.void * philosopher5(){ int i=0;
printf("\n\t\tPHILOSOPHER-5 THINKING.\n");
while(i<EATINGTIME) { sleep(1);
sem_wait(&sem45); sem_wait(&sem15);
Department Of Computer Science BM II College Of Engineering, Sasthamcotta32
Network-OS Lab Manual
printf("\n\t\t\t* PHILOSOPHER-5 EATING.*\n"); sleep(1); sem_post(&sem45); sem_post(&sem15);
printf("\n\t\tPHILOSOPHER-5 THINKING.\n"); i++; } end++;}
Output
Department Of Computer Science BM II College Of Engineering, Sasthamcotta33
Network-OS Lab Manual
BANKER’S ALGORITHM
Department Of Computer Science BM II College Of Engineering, Sasthamcotta34
Network-OS Lab Manual
Theory
The Banker's algorithm is a resource allocation & deadlock avoidance algorithm
developed by Edsger Dijkstra that tests for safety by simulating the allocation of pre-
determined maximum possible amounts of all resources, and then makes a "safe-state" check
to test for possible deadlock conditions for all other pending activities, before deciding
whether allocation should be allowed to continue.
The algorithm was developed in the design process for the THE operating system and
originally described (in Dutch) in EWD108[1]. The name is by analogy with the way that
bankers account for liquidity constraints.
The Banker's algorithm is run by the operating system whenever a process requests
resources.The algorithm prevents deadlock by denying or postponing the request if it
determines that accepting the request could put the system in an unsafe state (one where
deadlock could occur).
Resources
For the Banker's algorithm to work, it needs to know three things:
How much of each resource each process could possibly request
How much of each resource each process is currently holding
How much of each resource the system has available
Some of the resources that are tracked in real systems are memory, semaphores and interface
access.
Example
Assuming that the system distinguishes between four types of resources, (A, B, C and D), the
following is an example of how those resources could be distributed. Note that this example
shows the system at an instant before a new request for resources arrives. Also, the types and
Department Of Computer Science BM II College Of Engineering, Sasthamcotta35
Network-OS Lab Manual
number of resources are abstracted. Real systems, for example, would deal with much larger
quantities of each resource.
Available system resources:
A B C D
3 1 1 2
Processes (currently allocated resources):
A B C D
P1 1 2 2 1
P2 1 0 3 3
P3 1 1 1 0
Processes (maximum resources):
A B C D
P1 3 3 2 2
P2 1 2 3 4
P3 1 1 5 0
Safe and Unsafe States
A state (as in the above example) is considered safe if it is possible for all processes to finish
executing (terminate). Since the system cannot know when a process will terminate, or how
many resources it will have requested by then, the system assumes that all processes will
eventually attempt to acquire their stated maximum resources and terminate soon afterward.
This is a reasonable assumption in most cases since the system is not particularly concerned
with how long each process runs (at least not from a deadlock avoidance perspective). Also,
if a process terminates without acquiring its maximum resources, it only makes it easier on
the system.
Given that assumption, the algorithm determines if a state is safe by trying to find a
hypothetical set of requests by the processes that would allow each to acquire its maximum
resources and then terminate (returning its resources to the system). Any state where no such
set exists is an unsafe state.
Department Of Computer Science BM II College Of Engineering, Sasthamcotta36
Network-OS Lab Manual
Example
We can show that the state given in the previous example is a safe state by showing that it is
possible for each process to acquire its maximum resources and then terminate.
1. P1 acquires 2 A, 1 B and 1 D more resources, achieving its maximum
o The system now still has 1 A, no B, 1 C and 1 D resource available
2. P1 terminates, returning 3 A, 3 B, 2 C and 2 D resources to the system
o The system now has 4 A, 3 B, 3 C and 3 D resources available
3. P2 acquires 2 B and 1 D extra resources, then terminates, returning all its resources
o The system now has 5 A, 3 B, 6 C and 6 D resources
4. P3 acquires 4 C resources and terminates
o The system now has all resources: 6 A, 4 B, 7 C and 6 D
5. Because all processes were able to terminate, this state is safe
Note that these requests and acquisitions are hypothetical. The algorithm generates them to
check the safety of the state, but no resources are actually given and no processes actually
terminate. Also note that the order in which these requests are generated – if several can be
fulfilled – doesn't matter, because all hypothetical requests let a process terminate, thereby
increasing the system's free resources.
For an example of an unsafe state, look at what would happen if process 2 were holding 1
more unit of resource B at the beginning.
Requests
When the system receives a request for resources, it runs the Banker's algorithm to determine
if it is safe to grant the request. The algorithm is fairly straight forward once the distinction
between safe and unsafe states is understood.
1. Can the request be granted?
o If not, the request is impossible and must either be denied or put on a waiting
list
Department Of Computer Science BM II College Of Engineering, Sasthamcotta37
Network-OS Lab Manual
2. Assume that the request is granted
3. Is the new state safe?
o If so grant the request
o If not, either deny the request or put it on a waiting list
Whether the system denies an impossible or unsafe request or makes it wait is an operating
system specific decision.
Continuing the previous examples, assume process 3 requests 2 units of resource C.
1. There is not enough of resource C available to grant the request
2. The request is denied
On the other hand, assume process 3 requests 1 unit of resource C.
1. There are enough resources to grant the request
2. Assume the request is granted
o The new state of the system would be:
Available system resources: A B C D
Free 3 1 0 2
Processes (currently allocated resources):
A B C D
P1 1 2 2 1
P2 1 0 3 3
P3 1 1 2 0
Processes (maximum resources):
A B C D
P1 3 3 2 2
Department Of Computer Science BM II College Of Engineering, Sasthamcotta38
Network-OS Lab Manual
P2 1 2 3 4
P3 1 1 5 0
1. Determine if this new state is safe
1. P1 can acquire 2 A, 1 B and 1 D resources and terminate
2. Then, P2 can acquire 2 B and 1 D resources and terminate
3. Finally, P3 can acquire 3 C resources and terminate
4. Therefore, this new state is safe
2. Since the new state is safe, grant the request
Finally, assume that process 2 requests 1 unit of resource B.
1. There are enough resources
2. Assuming the request is granted, the new state would be:
Available system resources:
A B C D
Free 3 0 1 2
Processes (currently allocated resources):
A B C D
P1 1 2 2 1
P2 1 1 3 3
P3 1 1 1 0
Processes (maximum resources):
A B C D
P1 3 3 2 2
P2 1 2 3 4
P3 1 1 5 0
1. Is this state safe? Assuming P1, P2, and P3 request more of resource B and C.
o P1 is unable to acquire enough B resources
o P2 is unable to acquire enough B resources
o P3 is unable to acquire enough C resources
Department Of Computer Science BM II College Of Engineering, Sasthamcotta39
Network-OS Lab Manual
o No process can acquire enough resources to terminate, so this state is not safe
2. Since the state is unsafe, deny the request
Algorithm
* The algorithm for the process is...........
1. Start.
2. Wait for the request.
3. If the request is for allocation then
i. Obtain the request.
ii. Check for safe state.
iii. If safe state detected then allocate resources.
Else put the request in the waiting stack.
Else (for deallocation)
i.Deallocate the resources.
ii. Process the request of the process in the
wait stack.
4. Stop.
Program
/* Program to demonstrate the working of the BANKERS ALGORITHM.
* This program gives a general idea of how the operating system process allocates
resources to the requesting processes.
* Here it is assumed that request are collected in a 'req_queue' whose type is stored in
'req_type'.
* It has been assumed that there are 3 processes which can request for 4 different types
of resources say A,B,C & D.
Department Of Computer Science BM II College Of Engineering, Sasthamcotta40
Network-OS Lab Manual
* The program works with certain assumed values as shown below.........
AVAILABLE RESOURCE MATRIX.
| A | B | C | D| |___|____|____|___|_ | 3 | 1 | 1 | 2|
CURRENTLY ALLOCATED RESOURCES.
| A | B | C | D | ___|___|____|____|____| P1| 1 | 2 | 2 | 2 | ___|___|____|____|____| P2| 1 | 0 | 3 | 3 | ___|___|____|____|____| P3| 1 | 1 | 1 | 0 | ___|___|____|____|____|
MAXIMUM REQUIRED RESOURCES.
| A | B | C | D | ___|___|___|___|___| P1| 3 | 3 | 2 | 2 | ___|___|___|___|___| P2| 1 | 2 | 3 | 4 | ___|___|___|___|___| P3| 1 | 1 | 1 | 0 | ___|___|___|___|___|
* This module can be compiled using 'cc bankersalgorithm.c' and executed using './a.out'
//inculsion.#include<stdio.h>
//macro definition#define cls() printf("\033[H\033[J")#define delay() for(h=0;h<30000;h++){for(k=0;k<30000;k++){}}
//function prototype.void getrequest(int);int issafe();void allocate(int);void deallocate(int);void display();
//global matrixes as shown above.int available_res[4],cur_allocated_res[3][4],max_req_res[3][4],request[4];
Department Of Computer Science BM II College Of Engineering, Sasthamcotta41
Network-OS Lab Manual
int main(){ int req_queue[10],wait_queue[10],req_type[10],i,j,h,k;
//inserting the assumed values. available_res[0]=3; available_res[1]=1; available_res[2]=1; available_res[3]=2;
cur_allocated_res[0][0]=1;cur_allocated_res[0][1]=2;cur_allocated_res[0][2]=2;cur_allocated_res[0][3]=1;
cur_allocated_res[1][0]=1;cur_allocated_res[1][1]=0;cur_allocated_res[1][2]=3;cur_allocated_res[1][3]=3;
cur_allocated_res[2][0]=1;cur_allocated_res[2][1]=1;cur_allocated_res[2][2]=1;cur_allocated_res[2][3]=1;
max_req_res[0][0]=3; max_req_res[0][1]=3; max_req_res[0][2]=2; max_req_res[0][3]=2;
max_req_res[1][0]=1; max_req_res[1][1]=2; max_req_res[1][2]=3; max_req_res[1][3]=4;
max_req_res[2][0]=1; max_req_res[2][1]=1; max_req_res[2][2]=1; max_req_res[2][3]=0;//assuming the request.
req_queue[0]=0;req_queue[1]=1;req_queue[2]=2;req_queue[3]=0;req_queue[4]=2;req_queue[5]=1;
req_type[0]=0;req_type[1]=0;req_type[2]=0;req_type[3]=1;req_type[4]=1;req_type[5]=1;
display(); i=0;j=0;
while(i<6) { cls(); printf("\n\t\t\tWaiting for the request.............\n");
delay(); printf("\n\tRequest obtained from the process P%d ",req_queue[i]+1); if(req_type[i]==0) { printf("for resource allocation.\n"); printf("\nGetting request.....\n");
getrequest(req_queue[i]);
Department Of Computer Science BM II College Of Engineering, Sasthamcotta42
Network-OS Lab Manual
printf("\nChecking safe state.....\n"); delay(); if(issafe()) { printf("\nSafe state detected....\nAllocating resources .......\n"); allocate(req_queue[i]); } else { printf("\nUnsafe state detected....\nInserting the process into waiting queue.\n"); j=j+1; wait_queue[j]=req_queue[i]; } }
else { printf("for resource deallocation.\n"); deallocate(req_queue[i]); printf("\nDeallocation done.\n\n%d processes in the wait queue\n",j); if(j>0) { while(j>0) { printf("\nConsidering the waiting queue process P%d\n",wait_queue[j]+1); getrequest(wait_queue[j]); printf("\nChecking safe state.\n"); delay(); if(issafe()) { printf("\nSafe state detected\nResources allocated\n"); allocate(wait_queue[j]); j--; } else { break; } } } } delay(); i++; }}
Department Of Computer Science BM II College Of Engineering, Sasthamcotta43
Network-OS Lab Manual
void getrequest(int i){ int j; for(j=0;j<4;j++) { request[j]=max_req_res[i][j]-cur_allocated_res[i][j]; }}
int issafe(){ int j; for(j=0;j<4;j++) { if(request[j]>available_res[j]) { return 0; } } return 1;}
void allocate(int i){ int j;
for(j=0;j<4;j++) { cur_allocated_res[i][j]=cur_allocated_res[i][j]+request[j]; available_res[j]=available_res[j]-request[j]; }}
void deallocate(int i){ int j;
for(j=0;j<4;j++) { available_res[j]=available_res[j]+cur_allocated_res[i][j]; cur_allocated_res[i][j]=0; }}
void display(){ int i,j;
Department Of Computer Science BM II College Of Engineering, Sasthamcotta44
Network-OS Lab Manual
char a[3];
cls(); printf("\n\n\n\n\n\n\n\n"); printf("_____________________________________________________________________________________"); printf("\n\n\n\n\t\t\t\tBANKERS ALGORITHM.\n"); printf("\t\t\t\t__________________\n\n\n"); printf("\n\n\n\n\t\tPRESS ENTER TO CONTINUE.................."); fgets(a,2,stdin); cls();
printf("\n\n\t\t\t\tDETAILS."); printf("\n\t\t\t\t________");
printf("\n\n\t\tNO OF PROCESSES:\tP1 P2 P3"); printf("\n\n\t\tNO OF RESOURCES:\tA B C D");
printf("\n\n\t\t\tThe status .............");
printf("\nThe available resources are.\n\t\tA B C D\n\t\t");
for(i=0;i<4;i++) { printf("%d ",available_res[i]); } printf("\nThe currently allocated resources are...\n\t\t A B C D\n\t\t");
for(i=0;i<3;i++) { printf("P%d ",i+1); for(j=0;j<4;j++) { printf("%d ",cur_allocated_res[i][j]); } printf("\n\t\t"); }
printf("\nThe maximum required resources are...\n\t\t A B C D\n\t\t");
for(i=0;i<3;i++) { printf("P%d ",i+1); for(j=0;j<4;j++) { printf("%d ",max_req_res[i][j]);
Department Of Computer Science BM II College Of Engineering, Sasthamcotta45
Network-OS Lab Manual
} printf("\n\t\t"); }
printf("\n\n\tPRESS ENTER TO START THE PROCESS...\n"); fgets(a,2,stdin);}
Output
Department Of Computer Science BM II College Of Engineering, Sasthamcotta46
Network-OS Lab Manual
Department Of Computer Science BM II College Of Engineering, Sasthamcotta47
Network-OS Lab Manual
Department Of Computer Science BM II College Of Engineering, Sasthamcotta48
Network-OS Lab Manual
Department Of Computer Science BM II College Of Engineering, Sasthamcotta49
Network-OS Lab Manual
FLOPPY SIZE
Program
/* Program to find the disk space details of the floppy disk.
* This program uses the function call 'statvfs()' to find the details.
* This program gives details about the 'TOTAL', 'FREE' and 'USED' spaces of the disk.
* To run this program initially a file named 'temp.c' should be copied on to the floppy disk.
* Then compile as usual (cc floppydisksize.c)and run the program(./a.out).
NOTE: In linux the path name for floppy drive is :/media/floppy/.......(After mounting)
*/
//inculsion#include<stdio.h>#include<sys/statvfs.h>
int main(){
//variables to store the disk spaces. unsigned long totalblocks,blocksize,freeblocks;
char * filename="/media/floppy/temp.c"; struct statvfs buf;
if(!statvfs(filename,&buf)) {
//retriving the total no. of blocks. totalblocks=buf.f_blocks;
//retriving the blocksize. blocksize=buf.f_bsize;
//retriving the free disk space.
Department Of Computer Science BM II College Of Engineering, Sasthamcotta50
Network-OS Lab Manual
freeblocks=buf.f_bfree;
printf("\n\tThe total disk size:\t%lu (bytes)\n",totalblocks*blocksize); printf("\n\tThe free disk space:\t%lu (bytes)\n",freeblocks*blocksize); printf("\n\tThe used disk space:\t%lu (bytes)\n",(totalblocks*blocksize)-(freeblocks*blocksize)); } else { printf("\nERROR:Cannot open the file specified.\n"); }}
Output
64 ./nw
336 .
FileSystem Size Used Avail Use % Mounted On
/dev/mapper/VolGroup00-Log Vo100
35G 3.2G 30G 10% /
/dev/hda1 99M 12M 82M 13% /boot
None 498M 0 498M 0% /dev/shm
Department Of Computer Science BM II College Of Engineering, Sasthamcotta51
Network-OS Lab Manual
PIPES
Theory
A pipe is a method of connecting the standard output of one process to the standard
input of another. Pipes are the eldest of the IPC tools, having been around since the earliest
incarnations of the UNIX operating system. They provide a method of one-way
communications (hence the term half-duplex) between processes.
This feature is widely used, even on the UNIX command line (in the shell).
When a process creates a pipe, the kernel sets up two file descriptors for use by the
pipe. One descriptor is used to allow a path of input into the pipe (write), while the other is
used to obtain data from the pipe (read). At this point, the pipe is of little practical use, as the
creating process can only use the pipe to communicate with itself.
While a pipe initially connects a process to itself, data traveling through the pipe
moves through the kernel. Under Linux, in particular, pipes are actually represented
internally with a valid inode. Of course, this inode resides within the kernel itself, and not
within the bounds of any physical file system. This particular point will open up some pretty
handy I/O doors for us, as we will see a bit later on.
At this point, the creating process typically forks a child process. Since a child
process will inherit any open file descriptors from the parent, we now have the basis for
multiprocess communication (between parent and child). It is at this stage, that a critical
decision must be made. In which direction do we desire data to travel? Does the child process
send information to the parent, or vice-versa? The two processes mutually agree on this issue,
and proceed to ``close'' the end of the pipe that they are not concerned with.
To access a pipe directly, the same system calls that are used for low-level file I/O
can be used (recall that pipes are actually represented internally as a valid inode).
Department Of Computer Science BM II College Of Engineering, Sasthamcotta52
Network-OS Lab Manual
To send data to the pipe, we use the write() system call, and to retrieve data from the
pipe, we use the read() system call. Remember, low-level file I/O system calls work with file
descriptors! However, keep in mind that certain system calls, such as lseek(), do not work
with descriptors to pipes.
To create a simple pipe with C, we make use of the pipe() system call. It takes a
single argument, which is an array of two integers, and if successful, the array will contain
two new file descriptors to be used for the pipeline.
SYSTEM CALL: pipe();
PROTOTYPE: int pipe( int fd[2] );
RETURNS: 0 on success
-1 on error: errno = EMFILE (no free descriptors)
EMFILE (system file table is full)
EFAULT (fd array is not valid)
NOTES: fd[0] is set up for reading, fd[1] is set up for writing
The popen() function creates a pipe between the calling program and the
command to be executed. The arguments topopen() are pointers to null-terminated strings.
The com-mand argument consists of a shell command line. The modeargument is an I/O
mode, either r for reading or w for writing. The value returned is a stream pointer such that
one can write to the standard input of the command, if the I/Omode is w, by writing to the
file stream and one can read from the standard output of the command, if the I/O mode is r,
by reading from the file stream.
The pclose() function closes a stream opened by popen() by closing the pipe. It
waits for the associated process to terminate and returns the termination status of the process
running the command language interpreter. This is the value returned by waitpid(2).
Department Of Computer Science BM II College Of Engineering, Sasthamcotta53
Network-OS Lab Manual
SIMPLE PIPES OR LOWLEVEL PIPES
Program
/* Program to demonstrate the creation and use of simple/low level pipe.
* This program creates a pipe that connects the child process with its parent process.
* Here the child process writes 'REQUEST FROM CHILD PROCESS.' on to the pipe
which is read by the parent process.
* The function 'fork()' is a system call used to create a child process.
* This module can be compiled using 'cc simplepipe.c' and executed using './a.out'
//inculsion#include<stdio.h>#include<sys/types.h>
int main(){
//array to store the pipe pointers returned by the pipe() function. int pipe_pointer[2];
//variable to store the child process id. pid_t child; char message[50];
//creating a pipe pipe(pipe_pointer);
//creating a child process. child=fork();
if(child==0) { printf("\nThe child process is writing.\n");
//closing the read pointer. close(pipe_pointer[0]);
//writing on to the pipe. write(pipe_pointer[1],"REQUEST FROM CHILD PROCESS.",sizeof("REQUEST FROM CHILD PROCESS.")); } else {
Department Of Computer Science BM II College Of Engineering, Sasthamcotta54
Network-OS Lab Manual
printf("\nThe parent process is reading.\n");
//closing the write pointer. close(pipe_pointer[1]);
//reading from the pipe. read(pipe_pointer[0],message,sizeof(message));
printf("\nThe parent has read:\n\n** %s **\n",message); }
close(pipe_pointer[0]); close(pipe_pointer[1]);}
Output
Department Of Computer Science BM II College Of Engineering, Sasthamcotta55
Network-OS Lab Manual
FORMATTED PIPE
/* Program to demonstrate the creation and use of formatted pipe.
* This program creates a formatted pipe which is connected to the system process
denoted by the command 'CMD'.
* The pipe is established for reading and the read content is displayed.
* This module can be compiled using 'cc formattedpipe.c' and executed './a.out'.*/
//inculsion part#include<stdio.h>#include<string.h>
#define CMD "cal"
int main(){ FILE *ptr; char message[100]; char cmd[20];
strcpy(cmd,CMD);//creating a formatted pipe.
ptr=popen(cmd,"r"); while( fgets(message,sizeof(message),ptr)!=NULL) { printf("%s",message); }
//closing the pipe. pclose(ptr);}
Department Of Computer Science BM II College Of Engineering, Sasthamcotta56
Network-OS Lab Manual
Output
Department Of Computer Science BM II College Of Engineering, Sasthamcotta57
Network-OS Lab Manual
SHARED MEMORY
Theory
In computing, shared memory is a memory that may be simultaneously accessed by
multiple programs with an intent to provide communication among them. Depending on
context, programs may run on the same physical processor or on separate ones. Using
memory for communication inside a single program, for example among its multiple threads,
is generally not referred to as shared memory.
In computer software, shared memory is a method of inter-process communication
(IPC), i.e. a way of exchanging data between programs running at the same time. One
process will create an area in RAM which other processes can access.
Since both processes can access the shared memory area like regular working
memory, this is a very fast way of communication (as opposed to other mechanisms of IPC
such as named pipes, Unix sockets or CORBA). On the other hand, it is less powerful, as for
example the communicating processes must be running on the same machine (whereas other
IPC methods can use a computer network).
IPC by shared memory is mainly used on Unix systems.
POSIX provides a standardized API for using shared memory, POSIX Shared
Memory. This uses the function shm_open from sys/mman.h.
Shared Memory is an efficeint means of passing data between programs. One
program will create a memory portion which other processes (if permitted) can access.
Department Of Computer Science BM II College Of Engineering, Sasthamcotta58
Network-OS Lab Manual
In the Solaris 2.x operating system, the most efficient way to implement shared
memory applications is to rely on the mmap() function and on the system's native virtual
memory facility. Solaris 2.x also supports System V shared memory, which is another way to
let multiple processes attach a segment of physical memory to their virtual address spaces.
When write access is allowed for more than one process, an outside protocol or mechanism
such as a semaphore can be used to prevent inconsistencies and collisions.
A process creates a shared memory segment using shmget()|. The original owner of a
shared memory segment can assign ownership to another user with shmctl(). It can also
revoke this assignment. Other processes with proper permission can perform various control
functions on the shared memory segment using shmctl(). Once created, a shared segment can
be attached to a process address space using shmat(). It can be detached using shmdt() (see
shmop()). The attaching process must have the appropriate permissions for shmat(). Once
attached, the process can read or write to the segment, as allowed by the permission
requested in the attach operation. A shared segment can be attached multiple times by the
same process. A shared memory segment is described by a control structure with a unique ID
that points to an area of physical memory. The identifier of the segment is called the shmid.
The structure definition for the shared memory segment control structures and prototypews
can be found in <sys/shm.h>.
Accessing a Shared Memory Segment
shmget() is used to obtain access to a shared memory segment. It is prottyped by:
int shmget(key_t key, size_t size, int shmflg);
The key argument is a access value associated with the semaphore ID. The size
argument is the size in bytes of the requested shared memory. The shmflg argument specifies
the initial access permissions and creation control flags.
When the call succeeds, it returns the shared memory segment ID. This call is also
used to get the ID of an existing shared segment (from a process requesting sharing of some
existing memory portion).
Department Of Computer Science BM II College Of Engineering, Sasthamcotta59
Network-OS Lab Manual
The following code illustrates shmget():
#include <sys/types.h>#include <sys/ipc.h> #include <sys/shm.h>
... key_t key; /* key to be passed to shmget() */ int shmflg; /* shmflg to be passed to shmget() */ int shmid; /* return value from shmget() */ int size; /* size to be passed to shmget() */
... key = ... size = ...shmflg) = ...
if ((shmid = shmget (key, size, shmflg)) == -1) { perror("shmget: shmget failed"); exit(1); } else { (void) fprintf(stderr, "shmget: shmget returned %d\n", shmid); exit(0); }...
Controlling a Shared Memory Segment
shmctl() is used to alter the permissions and other characteristics of a shared memory segment. It is prototyped as follows:
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
The process must have an effective shmid of owner, creator or superuser to perform this command. The cmd argument is one of following control commands:
SHM_LOCK -- Lock the specified shared memory segment in memory. The process must have the effective ID of superuser to perform this command.
SHM_UNLOCK -- Unlock the shared memory segment. The process must have the effective ID of superuser to perform this command.
IPC_STAT -- Return the status information contained in the control structure and place it in the buffer pointed to by buf. The process must have read permission on the segment to perform this command.
IPC_SET
Department Of Computer Science BM II College Of Engineering, Sasthamcotta60
Network-OS Lab Manual
-- Set the effective user and group identification and access permissions. The process must have an effective ID of owner, creator or superuser to perform this command.
IPC_RMID -- Remove the shared memory segment.
The buf is a sructure of type struct shmid_ds which is defined in <sys/shm.h>
Program
Server
/*Program to demonstrate the use of shared memory in interprocess communication.
* This program acts as a server which waits for a message from the client process.
* The process is implemented using a shared memory space called 'shared_location'.
* The 'message' part of this space stores the message while the 'written' part is used to
indicate whether the server has read the message or the client has written the
message.(0->read,1->written).
* This module should be compiled and executed first.
* This module is compile using 'cc shmserver.c' and executed using './a.out'*/
//inculsion#include<stdio.h>#include<unistd.h>#include<string.h>
#include<sys/types.h>#include<sys/ipc.h>#include<sys/shm.h>
//structure definition for acquiring a shared location.struct shared_location{ int written; char message[30];};
int main(){ int shmid,running;
Department Of Computer Science BM II College Of Engineering, Sasthamcotta61
Network-OS Lab Manual
void *address; struct shared_location * ptr;
//for getting a shared location shmid=shmget((key_t)1234,sizeof(struct shared_location),0666|IPC_CREAT);
//optional if required for error checking. if(shmid<=0) { printf("\nERROR:\tCannot allocate shared space.\n"); exit(0); }
//attaching the shared location to this process. address=shmat(shmid,(void *)0,0);
//optional if required for error checking. if(address==(void*)0) { printf("\nEROOR:\tShared location cannot be attached.\n"); }
//type casting so as to convert the obyained location into our format. ptr=(struct shared_location*)address;
ptr->written=0; strcpy(ptr->message,"Hi I am server."); running=1;
while(running) { printf("\nWaiting for the client to enter the message.\n"); while(ptr->written==0) { } if(ptr->written==1) { printf("The client has entered the message: %s\n",ptr->message); } ptr->written=0; if(strcmp(ptr->message,"end")==0) { running=0; } }
//detaching the shared location. shmdt(address);
Department Of Computer Science BM II College Of Engineering, Sasthamcotta62
Network-OS Lab Manual
//deleting the shared location. shmctl(shmid,IPC_RMID,NULL);}
Output
Client
Program
/* Program to demonstrate the use of shared memory in interprocess communication.
* This module acts as a client which sends messages to the server process.
* In this the message entered into the message part of the 'shared_location' structure and
the 'written' field is set to 1.
* The remaining process is similar to that of the server process.
* This module can be compiled using 'cc shmclient.c -o b' and executed using './b'
//inculsion
Department Of Computer Science BM II College Of Engineering, Sasthamcotta63
Network-OS Lab Manual
#include<stdio.h>#include<unistd.h>#include<string.h>
#include<sys/types.h>#include<sys/ipc.h>#include<sys/shm.h>
//structure definition for the shared location.struct shared_location{ int written; char message[30];};//the functions and other terms used have similar meanings to that used in the server module //but they don't bear any specific relationship.
int main(){ int shmid,running; void *address; struct shared_location * ptr;
shmid=shmget((key_t)1234,sizeof(struct shared_location),0666|IPC_CREAT); if(shmid<=0) { printf("\nERROR:\tCannot allocate shared memory.\n"); exit(0); }
address=shmat(shmid,(void*)0,0); if(address==(void*)0) { printf("\nERROR:\tCannot attach the shared location\n"); exit(0); }
ptr=(struct shared_location*)address; running=1;
while(running) { printf("\nWaiting for the server\n"); while(ptr->written==1) { } printf("\nEnter your message.(type 'end' to exit)\n");
Department Of Computer Science BM II College Of Engineering, Sasthamcotta64
Network-OS Lab Manual
scanf("%s",ptr->message); ptr->written=1; if(strcmp(ptr->message,"end")==0) { running=0; } } address=shmat(shmid,(void *)0,0); shmdt(address);}
Output
Department Of Computer Science BM II College Of Engineering, Sasthamcotta65
Network-OS Lab Manual
SOME SAMPLE PROGRAMS
1.Program for executing LINUX commands through C program using system command
#include<stdio.h>main(){printf("\nDirectory Listing\n");system("ls -l");printf("Directory Listing Completed");}
Using exec command
#include<stdio.h>main(){printf("\nThe Directory Listing\n");execl("/bin/ls","ls","-l",NULL);printf("This Line will not be printed");}
2.Program to fork a child process and display details of parent & child processes
#include<sys/types.h>main(){int pid;pid=fork();if(pid==0){printf("I am child,My id is %d\n & my parents id is %d\n\n",getpid(),getppid());}else{printf("I am parent,My id is %d\n\n",getpid());printf("My child is %d\n\nMy Parent is %d",pid,getppid());}}
Department Of Computer Science BM II College Of Engineering, Sasthamcotta66
Network-OS Lab Manual
3.Program to call a new process using EXEC function from a child process
#include<sys/types.h>main(){int pid;printf("Program begins\n\n");pid=fork();
if(pid==0){
printf("I am child,My id is %d\n & my parents id is %d\n\n",getpid(),getppid());execl("f2",0);printf("Child Terminated");}else{printf("I am parent,My id is %d\n\n",getpid());printf("My child is %d\n\nMy Parent is %d",pid,getppid());}}
// Create another simple program. Compile it to f2( redirect output to f2). f2 will be executed by the above written program.
3. Program to demonstrate interprocess communication between a parent process and a child process.
//This is to and fro communication through a single pipe.
#include<stdio.h>#include<sys/types.h>
main(){int pid,fd[2];char buf[50];pipe(fd);pid=fork();if(pid==0){
printf("%d %d",pid,getppid());
Department Of Computer Science BM II College Of Engineering, Sasthamcotta67
Network-OS Lab Manual
printf("Enter the data for the parent");fgets(buf,sizeof(buf),stdin);write(fd[1],buf,sizeof(buf));sleep(20);read(fd[0],buf,sizeof(buf));printf("Got From Parent");puts(buf);
}else{
sleep(10);printf("In Child %d %d ",pid,getppid());read(fd[0],buf,sizeof(buf));printf("From Child");puts(buf);printf("I am Parent");printf("Enter message for Child");fgets(buf,sizeof(buf),stdin);write(fd[1],buf,sizeof(buf));
}}
5.Suppose we are given a number N which is quite large. We need to find all its factors. We decide to have some computation in parallel so we divide the N by the range of numbers from 2 to √N/2 and √N/2 +1. We fork two child processes to work over each of these ranges. Write a program to implement the above scheme using fork(). The parent should output only distinct factors.
#include<stdio.h>#include<sys/types.h>#include<unistd.h>
void firstfact(int n);void secondfact(int n);int i,j=0;main(){int fd1[2],fd2[2],n,j=0,i,pid1,pid2;int factor[20];pipe(fd1);pipe(fd2);pid1=fork();if(pid1){
pid2=fork(); //child1
Department Of Computer Science BM II College Of Engineering, Sasthamcotta68
Network-OS Lab Manual
if(pid2==0){
read(fd1[0],&n,sizeof(n));firstfact(n);
}//parentelse{scanf("%d",&n);write(fd1[1],&n,sizeof(n));write(fd2[1],&n,sizeof(n));}
}
//child2else{
read(fd2[0],&n,sizeof(n)); secondfact(n);
}}
void firstfact(int n){
for(i=2;i<(sqrt(n)/2);i++){if(n%i==0)
{//printf("child");
printf("\n%d >>>>child1",i); }
}
}void secondfact(int n){
for(i=((sqrt(n/2)+1);i<=(n/2);i++){
if(n%i==0){
Department Of Computer Science BM II College Of Engineering, Sasthamcotta69
Network-OS Lab Manual
//printf("parent");printf("\n%d >>>child2",i);}
}
}
6. Write a program to detect deadlock when a number of processes are running. The number of available resources, number of resources allocated to processes are accepted..
#include<stdio.h>
void read_alloc(int A[10][10],int m , int n ){
int i ,j ;for(i=0;i<n;i++){printf("for process %d the no: of allocated resources of .....\n",i);for(j=0;j<m;j++){printf("type%d:",j);
scanf ("%d",&A[i][j]);}}
}void read_reqst(int RQ[10][10],int m,int n){
int i ,j ;for (i=0;i<n;i++){printf("for process %d the no: of required resources of .....\n",i);
for(j=0;j<m;j++){printf("type%d:",j);
scanf ("%d",&RQ[i][j]);}}
}void read_avail(int A[10],int m ){ int i ;
printf("Enter the available resources of ........\n");
Department Of Computer Science BM II College Of Engineering, Sasthamcotta70
Network-OS Lab Manual
for (i=0;i<m ;i++){printf("Type %d ",i);scanf("%d",&A[i]);}
}void calc_deadlock(int A[10][10],int RQ[10][10],int AVAIL[10],int m,int n ){
int w[10],f[10],i,j,fg=0;for(i=0;i<m;i++)w[i]=AVAIL[i];for(i=0;i<n;i++){
fg=0;for(j=0;j<m;j++){if (A[i][j]!=0){fg=1;
break;}}
if (fg==0)f[i]=1;else
f[i]=0;}for(i=0;i<n;i++){
fg=0;for(j=0;j<n;j++){if (RQ[i][j]>w[j]){
fg=1; break;
}}if(fg==0 && f[i]==0){for(j=0;j<m;j++)w[j]=w[j]+A[i][j];f[i]=1;i=0;}
}
Department Of Computer Science BM II College Of Engineering, Sasthamcotta71
Network-OS Lab Manual
fg=0;for(i=0;i<n;i++){
if (f[i]==0){
printf(" the system is in deadlock by the process %d ....",i);getchar();fg=1;break;}}
if (fg==0){printf(" there is no deadlock");getchar();}
}
int main(){int m , n , A[10][10],AVAIL[10],RQ[10][10];system("clear");printf("enter the total number of processes running:");scanf("%d",&n);printf (" enter the total no: of resource types :");scanf ("%d",&m);read_alloc(A,m,n);system("clear");read_reqst(RQ,m,n);system("clear");read_avail(AVAIL,m);calc_deadlock(A,RQ,AVAIL,m,n);getchar();}
7.Write a program to send and receive messages through message queue
Sending Program
//Message Queue....Sending Data...
#include<stdio.h>#include<string.h>#include<stdlib.h>#include<unistd.h>#include<sys/types.h>
Department Of Computer Science BM II College Of Engineering, Sasthamcotta72
Network-OS Lab Manual
#include<sys/ipc.h>#include<sys/msg.h>typedef struct msgbuf{
long mtype;char data[30];
}message;int main(){
message send,rec;key_t key=3151; //else use FTOK function to generate a unique key value
int msgid=msgget(key,IPC_CREAT|0666);if(msgid==-1){
fprintf(stderr,"Error Creating Or Opening mq\n");return EXIT_FAILURE;
}do{
fprintf(stdout,"Enter Some Valid Data To Send");fgets(send.data,30,stdin);send.mtype=1;if(msgsnd(msgid,(void *)& send,30,1)==-1){
fprintf(stderr,"Error Writting To mq\n");return EXIT_FAILURE;
}}while(strncmp(send.data,"quit",4)!=0);
return EXIT_SUCCESS;}
Receiving Program
//Message Queue....Receiving Data...
#include<stdio.h>#include<string.h>#include<stdlib.h>#include<unistd.h>#include<sys/types.h>#include<sys/ipc.h>#include<sys/msg.h>typedef struct msgbuf{
Department Of Computer Science BM II College Of Engineering, Sasthamcotta73
Network-OS Lab Manual
long mtype;char data[30];
}message;
int main(){
message send,rec;student s;int i;key_t key=3151;sleep(20);printf("In Process 2");
int msgid=msgget(key,IPC_CREAT|0666);if(msgid==-1){
fprintf(stderr,"Error Creating Or Opening mq\n");return EXIT_FAILURE;
}sleep(20);int j=0;do{
j++;if(msgrcv(msgid,(void *)&rec,30,1,0)==-1){
fprintf(stderr,"Error Writting To mq\n");break;
}fprintf(stdout,"Receiver Got %s\n",rec.data);
}while(strncmp(send.data,"quit",4)!=0);
}
8.Suppose we have 4 matrices A , B, C and D , each of size N X N , we need to compute the matrix product A X B, A X C , A X D . Write a pgm to compute the desired result using shared memory mechanism.
//MATRIX MULTIPLICATION(SHM1.C)#include<stdio.h>#include<sys/shm.h>#include<sys/stat.h>
Department Of Computer Science BM II College Of Engineering, Sasthamcotta74
Network-OS Lab Manual
#include<string.h>#include<sys/types.h>#include<unistd.h>#define size 4096
//CONVERTING STARTING ADDRESS OF SHARED MEMORY TO STRINGvoid itoa(char *str,int n){ int i=100000,j=0; for(j=0;j<6;++j)
{ str[j]=n/i+48; n=n%i; i=i/10;}str[j]='\0';
}
//READ MATRIX FROM KEYBOARD AND STORE TO SHARED MEMORYvoid read_matrix(int address,int A[10][10],int r,int c,int *shared_mem){
int i,j;for(i=0;i<r;++i){
printf("\n");for(j=0;j<c;++j){ scanf("%d",&A[i][j]); shared_mem[address]=A[i][j]; address++;}
}}
// MATRIX MULTIPLICATION
void multiply(int A[10][10],int B[10][10],int r1,int c1,int r2,int c2){
int i,j,k,C[10][10];for(i=0;i<r1;++i){
for(j=0;j<c1;++j){
Department Of Computer Science BM II College Of Engineering, Sasthamcotta75
Network-OS Lab Manual
C[i][j]=0;for(k=0;k<r2;++k)C[i][j]+=A[i][k]*B[k][j];
}}
printf("The result of A X B from process 1 is ..............\n");for(i=0;i<r1;++i){
printf("\n");for(j=0;j<c2;++j) printf("%8d",C[i][j]);
}}
int main(){
int sh_mem_id, *shared_mem;int r1,r2,c1,c2,r3,c3;int address=8,A[10][10],B[10][10],C[10][10];char str[10];pid_t child;
//INITIALIZE SHARED MEMORYsh_mem_id=shmget(IPC_PRIVATE,size,IPC_CREAT|IPC_EXCL|S_IRUSR|
S_IWUSR|S_IROTH|S_IWOTH);shared_mem=(int *)shmat(sh_mem_id,0,0);//ATTACH MEMORY
//CONVERT ADDRESS TO STRINGitoa(str,sh_mem_id);
system("clear");printf("Enter the rows and columns of matrix A.....\n");scanf("%d %d",&r1,&c1);
//STORE ROW AND COLUMN TO SHARED MEMORYshared_mem[0]=r1;shared_mem[1]=c1;
printf("\nEnter the elements of the matrix A....\n");read_matrix(address,A,r1,c1,shared_mem);
//INCREMENT SHARED MEMORY ADDRESSaddress=address+(r1*c1);
//FOR MATRIX B
Department Of Computer Science BM II College Of Engineering, Sasthamcotta76
Network-OS Lab Manual
system("clear");printf("enter the rows and columnsof matrix B....\n");scanf("%d %d",&r2,&c2);shared_mem[2]=r2;shared_mem[3]=c2;printf("enter the elementsof matrix B....\n");read_matrix(address,B,r2,c2,shared_mem);address=address+(r2*c2);
//FOR MATRIX Csystem("clear");printf("enter the rows and columnsof matrix C....\n");scanf("%d %d",&r3,&c3);shared_mem[4]=r3;shared_mem[5]=c3;printf("enter the elementsof matrix C....\n");read_matrix(address,C,r3,c3,shared_mem);address=address+(r3*c3);
//FOR MATRIX D system("clear");printf("enter the rows and columnsof matrix D.....\n");scanf("%d %d",&r3,&c3);shared_mem[6]=r3;shared_mem[7]=c3;printf("enter the elementsof matrix D...\n");read_matrix(address,C,r3,c3,shared_mem);address=address+(r3*c3);
//FORK A CHILDchild=fork();if(child ==0){
sleep(10);//INVOKE ANOTHER PROGRAM SHM2(EXE),PASS ARGUMENT- STR
execlp("./shm2","shm2",str,NULL);}multiply(A,B,r1,c1,r2,c2);shmdt(shared_mem);//DETACH SHARED MEMORYprintf("closing process 1...............\n");
}
//Process1 reads matrices from keyboard and stores to shared memory. AXB is simple computation without using shared memory. Write another program (shm2.c) The Shared
Department Of Computer Science BM II College Of Engineering, Sasthamcotta77
Network-OS Lab Manual
memory id is passed to this program through exec function. Exec takes only string arguments. So id value is converted to string.Shm2.c is compiled to shm2 and is called from process1.You have to run only process1. Locations 0 to 7 of shared memory contain number of rows and columns of 4 matrices. Actual matrix elements are stored from location 8 onwards.………………………………………………………………………………………………………………………………………………………………………………………….
shm2.c
//SHM2.C//COMPILE THIS TO SHM2
#include<stdio.h>#include<sys/shm.h>#include<sys/stat.h>#include<string.h>#include<sys/types.h>#include<unistd.h>#include<stdlib.h>
//READ THE MATRIX FROM SHARED MEMORYvoid read_from_shm(int A[10][10],int *shared_mem,int add,int r,int c){
int i,j;for(i=0;i<r;++i){
for(j=0;j<c;++j){ A[i][j]=shared_mem[add]; add++;}
}}
void multiply(int A[10][10],int B[10][10],int r1,int c1,int r2,int c2){
int i,j,k,C[10][10];for(i=0;i<r1;++i){
for(j=0;j<c1;++j){
C[i][j]=0;for(k=0;k<r2;++k)
Department Of Computer Science BM II College Of Engineering, Sasthamcotta78
Network-OS Lab Manual
C[i][j]+=A[i][k]*B[k][j];}
}
for(i=0;i<r1;++i){
printf("\n");for(j=0;j<c2;++j) printf("%8d",C[i][j]);
}}
int main(int argc,char *argv[]){
int *shared_mem,sh_mem_id;int r1,c1,r2,c2,r3,c3,add=8;int A[10][10],C[10][10],D[10][10];pid_t child;
//GET STARTING ADDRESS OF SHARED MEMORY FROM COMMAND LINE ARGUMENT
sh_mem_id=atoi(argv[1]);shared_mem=(int *)shmat(sh_mem_id,0,0);//ATTACH MEMORY
system("clear");//GET ROW& COLUMN FROM SHARED MEMORYr1=shared_mem[0];c1=shared_mem[1];//READ MATRIX Aread_from_shm(A,shared_mem,add,r1,c1);add=add+(r1*c1);
//SKIP MATRIX Br2=shared_mem[2];c2=shared_mem[3];add=add+(r2*c2);
//READ MATRIX Cr3=shared_mem[4];c3=shared_mem[5];read_from_shm(C,shared_mem,add,r3,c3);add=add+(r3*c3);printf("\n The Result of A X C from process 2.......\n");
multiply(A,C,r1,c1,r3,c3);
Department Of Computer Science BM II College Of Engineering, Sasthamcotta79
Network-OS Lab Manual
//READ MATRIX Dr3=shared_mem[6];c3=shared_mem[7];read_from_shm(D,shared_mem,add,r3,c3);sleep(3);printf("\n.. The Result of A X D from process 2..............\n");multiply(A,D,r1,c1,r3,c3);
printf("closing process 2.......\n");
//DETACH MEMORY shmdt(shared_mem);
//REMOVE MEMORYshmctl(sh_mem_id,IPC_RMID,0);
}
9. Implement Producer Consumer Problem
//CONSUMER PROGRAM
#include <stdio.h>#include <string.h>#include <unistd.h>#include <fcntl.h>
#define BUF_SIZE 30
int main(){ char write_fifo[] = "readFIFO"; char read_fifo[] = "writeFIFO";
//Check if the FIFO exists. If not, try to create it. if( access(write_fifo, F_OK)==-1 )
{ int result = mkfifo(write_fifo, 0777); if( result!=0 )
{ fprintf(stderr, "FIFO creation failed."); return 1;
Department Of Computer Science BM II College Of Engineering, Sasthamcotta80
Network-OS Lab Manual
} } if( access(read_fifo, F_OK)==-1 ){ int result = mkfifo(read_fifo, 0777); if( result!=0 ) { fprintf(stderr, "FIFO creation failed."); return 1; } } int r_pipe = open(read_fifo, O_RDONLY); int w_pipe = open(write_fifo, O_WRONLY);
if( w_pipe==-1 ) { fprintf(stderr, "Error opening %s\n", write_fifo); return 2; } if( r_pipe==-1 ) { fprintf(stderr, "Error opening %s\n", read_fifo); return 2; }
int bytes=0, i; char w_buffer[BUF_SIZE], r_buffer[BUF_SIZE]; do { //Read the string from the pipe. memset(r_buffer, '\0', sizeof(r_buffer)); read(r_pipe, r_buffer, sizeof(r_buffer)); fprintf(stdout, "I got %s\n", r_buffer); //Process the string; strcpy(w_buffer, r_buffer); for(i=0;i<strlen(w_buffer);++i) w_buffer[i] = w_buffer[i]+1;
//Write the string back into the pipe. bytes = write(w_pipe, w_buffer, strlen(w_buffer)); if( bytes==-1 ) fprintf(stderr, "Write error in FIFO!\n"); }while( strncmp(r_buffer, "quit", 4)!=0 );
close(w_pipe);
Department Of Computer Science BM II College Of Engineering, Sasthamcotta81
Network-OS Lab Manual
close(r_pipe);
fprintf(stdout, "WORKING Process finished [PID=%d]\n", (int)getpid() );
return 0;}
//PRODUCER PROGRAM
#include <stdio.h>#include <string.h>#include <unistd.h>#include <fcntl.h>
#define BUF_SIZE 30
int main(){ char write_fifo[] = "writeFIFO"; char read_fifo[] = "readFIFO";
//Check if the FIFO exists. If not, try to create it. if( access(write_fifo, F_OK)==-1 ){ int result = mkfifo(write_fifo, 0777); if( result!=0 ){ fprintf(stderr, "FIFO creation failed."); return 1; } } if( access(read_fifo, F_OK)==-1 ){ int result = mkfifo(read_fifo, 0777); if( result!=0 ){ fprintf(stderr, "FIFO creation failed."); return 1; } } int w_pipe = open(write_fifo, O_WRONLY); int r_pipe = open(read_fifo, O_RDONLY); if( w_pipe==-1 ){ fprintf(stderr, "Error opening %s\n", write_fifo); return 2; } if( r_pipe==-1 ){
Department Of Computer Science BM II College Of Engineering, Sasthamcotta82
Network-OS Lab Manual
fprintf(stderr, "Error opening %s\n", read_fifo); return 2; }
int bytes; char w_buffer[BUF_SIZE], r_buffer[BUF_SIZE];
do{ fprintf(stdout, "Enter something to be sent for PROCESSING :"); fgets(w_buffer, BUF_SIZE-1, stdin); w_buffer[strlen(w_buffer)-1] = '\0';
//Write the string into the pipe. bytes = write(w_pipe, w_buffer, strlen(w_buffer)); if( bytes<0 ) fprintf(stderr, "Error writing to pipe! Data lost??"); //Read string from pipe, after processing. memset(r_buffer, '\0', sizeof(r_buffer)); read(r_pipe, r_buffer, sizeof(r_buffer)); fprintf(stdout, "The string after processing is :%s\n", r_buffer); }while( strncmp(w_buffer, "quit", 4)!=0 );
close(w_pipe); close(r_pipe);
fprintf(stdout, "IO Handler Process finished [PID=%d]\n", (int)getpid() ); return 0;}
//Producer program produces items and writes to a FIFO. Consumer reads this FIFO and processes the items. The processed items are written to another FIFO. This is read by the producer.
GENERAL INSTRUCTIONS
For programs that are sender-receiver or client-server type(ftp, mac, smtp, ipc using sockets, messageQ, named pipes)g++ <sender.c> -o senderg++ <receiver.c> -o recv
then run in 2 terminals(always server/receiver first) as:./recv <port>./sender <IP> <port>
if its not a NW pgm(eg: msgQs, named pipes) just run as:
Department Of Computer Science BM II College Of Engineering, Sasthamcotta83
Network-OS Lab Manual
./recv
./sender
compiling RPC:
there are 3 files initially, which we code... finger.x, client.c, server.c
compile in the following order...
do this in both the client and server systems
rpcgen -C finger.x (thats a C, not c)gcc -c client.c -o clientgcc -c server.c -o servergcc -c finger_clnt.c -o f_cgcc -c finger_svc.c -o f_sgcc -c finger_xdr.c -o f_x
In the server system, do:gcc -o fs server f_s f_x
In the client system, do:gcc -o fc client f_c f_x
Now run as before,./fs <port>./fc <IP> <port>
For threaded programs, compile withg++ <program.cpp> -lpthread
For dining philosopher using ncurses lib, g++ dining.cpp -lpthread -lcursesif that doesn't workg++ -I/usr/include/ncurses dining.cpp -lpthread
Department Of Computer Science BM II College Of Engineering, Sasthamcotta84
Network-OS Lab Manual
NETWORKING
Department Of Computer Science BM II College Of Engineering, Sasthamcotta85
Network-OS Lab Manual
SOCKET PROGRAMMING
Theory
Sockets provide point-to-point, two-way communication between two processes.
Sockets are very versatile and are a basic component of interprocess and intersystem
communication. A socket is an endpoint of communication to which a name can be bound. It
has a type and one or more associated processes.
Sockets exist in communication domains. A socket domain is an abstraction that
provides an addressing structure and a set of protocols. Sockets connect only with sockets in
the same domain. Twenty three socket domains are identified (see <sys/socket.h>), of which
only the UNIX and Internet domains are normally used Solaris 2.x Sockets can be used to
communicate between processes on a single system, like other forms of IPC.
The UNIX domain provides a socket address space on a single system. UNIX domain
sockets are named with UNIX paths. Sockets can also be used to communicate between
processes on different systems. The socket address space between connected systems is
called the Internet domain.
Internet domain communication uses the TCP/IP internet protocol suite.
Socket types define the communication properties visible to the application.
Processes communicate only between sockets of the same type. There are five types of
socket.
A stream socket
-- provides two-way, sequenced, reliable, and unduplicated flow of data with no
record boundaries. A stream operates much like a telephone conversation. The socket
Department Of Computer Science BM II College Of Engineering, Sasthamcotta86
Network-OS Lab Manual
type is SOCK_STREAM, which, in the Internet domain, uses Transmission Control
Protocol (TCP).
A datagram socket
-- supports a two-way flow of messages. A on a datagram socket may receive
messages in a different order from the sequence in which the messages were sent.
Record boundaries in the data are preserved. Datagram sockets operate much like
passing letters back and forth in the mail. The socket type is SOCK_DGRAM, which,
in the Internet domain, uses User Datagram Protocol (UDP).
A sequential packet socket
-- provides a two-way, sequenced, reliable, connection, for datagrams of a fixed
maximum length. The socket type is SOCK_SEQPACKET. No protocol for this type
has been implemented for any protocol family.
A raw socket
provides access to the underlying communication protocols.
These sockets are usually datagram oriented, but their exact characteristics depend on the
interface provided by the protocol.
Socket Creation and Naming
int socket(int domain, int type, int protocol) is called to create a socket in the
specified domain and of the specified type. If a protocol is not specified, the system
defaults to a protocol that supports the specified socket type. The socket handle (a
descriptor) is returned. A remote process has no way to identify a socket until an address
is bound to it. Communicating processes connect through addresses. In the UNIX
domain, a connection is usually composed of one or two path names. In the Internet
domain, a connection is composed of local and remote addresses and local and remote
ports. In most domains, connections must be unique.
int bind(int s, const struct sockaddr *name, int namelen) is called to bind a path or
internet address to a socket. There are three different ways to call bind(), depending on
the domain of the socket.
Department Of Computer Science BM II College Of Engineering, Sasthamcotta87
Network-OS Lab Manual
For UNIX domain sockets with paths containing 14, or fewer characters, you can:
#include <sys/socket.h>
...
bind (sd, (struct sockaddr *) &addr, length);
If the path of a UNIX domain socket requires more characters, use:
#include <sys/un.h>
...
bind (sd, (struct sockaddr_un *) &addr, length);
For Internet domain sockets, use
#include <netinet/in.h>
...
bind (sd, (struct sockaddr_in *) &addr, length);
In the UNIX domain, binding a name creates a named socket in the file system. Use unlink()
or rm () to remove the socket.
Connecting Stream Sockets
Connecting sockets is usually not symmetric. One process usually acts as a server and the
other process is the client. The server binds its socket to a previously agreed path or address.
It then blocks on the socket. For a SOCK_STREAM socket, the server calls int listen(int s,
int backlog) , which specifies how many connection requests can be queued. A client initiates
a connection to the server's socket by a call to int connect(int s, struct sockaddr *name, int
namelen) . A UNIX domain call is like this:
struct sockaddr_un server;
...
connect (sd, (struct sockaddr_un *)&server, length);
while an Internet domain call would be:
struct sockaddr_in;
...
Department Of Computer Science BM II College Of Engineering, Sasthamcotta88
Network-OS Lab Manual
connect (sd, (struct sockaddr_in *)&server, length);
If the client's socket is unbound at the time of the connect call, the system automatically
selects and binds a name to the socket. For a SOCK_STREAM socket, the server calls
accept(3N) to complete the connection.
int accept(int s, struct sockaddr *addr, int *addrlen) returns a new socket descriptor which is
valid only for the particular connection. A server can have multiple SOCK_STREAM
connections active at one time.
Stream Data Transfer and Closing
Several functions to send and receive data from a SOCK_STREAM socket. These are
write(), read(), int send(int s, const char *msg, int len, int flags), and int recv(int s, char *buf,
int len, int flags). send() and recv() are very similar to read() and write(), but have some
additional operational flags.
The flags parameter is formed from the bitwise OR of zero or more of the following:
MSG_OOB
-- Send "out-of-band" data on sockets that support this notion. The underlying
protocol must also support "out-of-band" data. Only SOCK_STREAM sockets
created in the AF_INET address family support out-of-band data.
MSG_DONTROUTE
-- The SO_DONTROUTE option is turned on for the duration of the operation. It is
used only by diagnostic or routing pro- grams.
MSG_PEEK
-- "Peek" at the data present on the socket; the data is returned, but not consumed, so
that a subsequent receive operation will see the same data.
A SOCK_STREAM socket is discarded by calling close().
Department Of Computer Science BM II College Of Engineering, Sasthamcotta89
Network-OS Lab Manual
Datagram sockets
A datagram socket does not require that a connection be established. Each message carries
the destination address. If a particular local address is needed, a call to bind() must precede
any data transfer. Data is sent through calls to sendto() or sendmsg(). The sendto() call is like
a send() call with the destination address also specified. To receive datagram socket
messages, call recvfrom() or recvmsg(). While recv() requires one buffer for the arriving
data, recvfrom() requires two buffers, one for the incoming message and another to receive
the source address.
Datagram sockets can also use connect() to connect the socket to a specified destination
socket. When this is done, send() and recv() are used to send and receive data.
accept() and listen() are not used with datagram sockets.
TRANSFER CONTROL PROTOCOL(TCP)
Server
Algorithm
The activity involved in a tcp server are.......... 1.Create a socket.
2.Bind it to the operating system.
3.Listen over it.
4.Accept connections.
5.Read/Write processes.
6.Close the socket.
Department Of Computer Science BM II College Of Engineering, Sasthamcotta90
Network-OS Lab Manual
Program
/*Program to demonstrate the creation and usage of tcp socket.
* This module acts as the tcp server which listens to a socket and accepts connection.
* The server initially reads a message from the client and then writes a message to it.
* This module should be compiled using the command. 'c++ tcpserver.cpp' and execute
'./a.out'.*/
//inculsion.#include<iostream>#include<stdio.h>
#include<sys/types.h>#include<netinet/in.h>#include<netdb.h>
int main(){
//variables to store the socket id. int serversocket,clientsocket;
//variables to store the network host addresses. sockaddr_in serveraddr,clientaddr;
//variable to store address length. socklen_t len; char message[50];
//creating a socket. serversocket=socket(AF_INET,SOCK_STREAM,0);
//steps to include the host address bzero((char*)&serveraddr,sizeof(serveraddr)); serveraddr.sin_family=AF_INET; serveraddr.sin_port=htons(5030); serveraddr.sin_addr.s_addr=INADDR_ANY;
//binding the socket to the operating system. bind(serversocket,(sockaddr*)&serveraddr,sizeof(serveraddr));
bzero((char*)&clientaddr,sizeof(clientaddr)); len=sizeof(clientaddr);
Department Of Computer Science BM II College Of Engineering, Sasthamcotta91
Network-OS Lab Manual
//listening over the socket. listen(serversocket,5);
printf("\nWaiting for client connectivity.\n");
//accepting the connection. clientsocket=accept(serversocket,(sockaddr*)&clientaddr,&len);
printf("\nClient connectivity received.\n");
printf("\nReading message from the client.\n");
//reading activity. read(clientsocket,message,sizeof(message));
printf("\nThe client has send:\t%s\n",message);
printf("\nSending message to the client.\n");
//writing activity. write(clientsocket,"YOUR MESSAGE RECEIVED.",sizeof("YOUR MESSAGE RECEIVED."));
close(clientsocket); close(serversocket);}
Output
Department Of Computer Science BM II College Of Engineering, Sasthamcotta92
Network-OS Lab Manual
Client
Algorithm
The different processes involved in a udp client process are........
1.Create a datagram socket.
2.Receive/Send message to the server.
3.Close the socket.
Program
/* Program to demonstrate the creation and usage of datagram sockets.
* This module acts as a udp client which sends and receives messages from a udp server.
* This module should be compiled into different folder using the command 'c++
udpclient.cpp -o b' and execute using './b'
* For execution the 'udpserver' module should be executed first then this module.
//inculsion.#include<iostream>#include<stdio.h>
#include<sys/types.h>#include<netinet/in.h>#include<netdb.h>
int main(){
//variable to store the socket_id. int clientsocket;
//variable to store the address. sockaddr_in serveraddr;
//variableto store the address length. socklen_t len;
//variable to store the network byte order address. hostent *server; char message[50];
//socket creation.
Department Of Computer Science BM II College Of Engineering, Sasthamcotta93
Network-OS Lab Manual
clientsocket=socket(AF_INET,SOCK_DGRAM,0);//steps involved in the server address creation.
bzero((char*)&serveraddr,sizeof(serveraddr)); len=sizeof(serveraddr); serveraddr.sin_family=AF_INET; serveraddr.sin_port=htons(5015); server=gethostbyname("127.0.0.1"); bcopy((char*)server->h_addr,(char*)&serveraddr.sin_addr.s_addr,sizeof(server->h_addr)); printf("\nPRESS ENTER TO START THE CONNECTION PROCESS.\n"); fgets(message,2,stdin);
printf("\nSending message for server connection\n");//sending message.
sendto(clientsocket,"HI I AM CLIENT...",sizeof("HI I AM CLIENT...."),0,(sockaddr*)&serveraddr,sizeof(serveraddr)); printf("\nReceiving message from server.\n");
//receiving messages. recvfrom(clientsocket,message,sizeof(message),0,(sockaddr*)&serveraddr,&len);
printf("\nMessage received:\t%s\n",message);
close(clientsocket);}
Output
Department Of Computer Science BM II College Of Engineering, Sasthamcotta94
Network-OS Lab Manual
USER DATAGRAM PROTOCOL(UDP)
Server
Algorithm
* The different process involved in an udp server process are.......
1.Create a datagram socket.
2.Bind the socket to the operating system.
3.Receive/Sending processes.
4.Close the socket.
Program
/* Program to demonstrate the creation and use of datagram socket.
* This module act as udp server which waits for client connection
* This server initially receives message from the client and then sends back a reply.
* This module should be comipled using the command 'c++ tcpserver.cpp' and execute './a.out'.
//inculsion.#include<iostream>#include<stdio.h>
#include<sys/types.h>#include<netinet/in.h>#include<netdb.h>
int main(){
//variable to store the socket_id. int serversocket;
//variable to store the network addresses. sockaddr_in serveraddr,clientaddr;
Department Of Computer Science BM II College Of Engineering, Sasthamcotta95
Network-OS Lab Manual
//variable to store the address length. socklen_t len; char message[50];
//socket creation. serversocket=socket(AF_INET,SOCK_DGRAM,0);
//steps involved in defining the serveraddress. bzero((char*)&serveraddr,sizeof(serveraddr)); serveraddr.sin_family=AF_INET; serveraddr.sin_port=htons(5015); serveraddr.sin_addr.s_addr=INADDR_ANY;
//binding the socket to the operating system. bind(serversocket,(sockaddr*)&serveraddr,sizeof(serveraddr));
printf("\nWaiting for the client connection\n");
bzero((char*)&clientaddr,sizeof(clientaddr)); len=sizeof(clientaddr);
//receiving message from the client. recvfrom(serversocket,message,sizeof(message),0,(sockaddr*)&clientaddr,&len);
printf("\nConnection received from client.\n");
printf("\nThe client has send:\t%s\n",message);
printf("\nSending message to the client.\n");
//sending message to the client. sendto(serversocket,"YOUR MESSAGE RECEIVED.",sizeof("YOUR MESSAGE RECEIVED."),0,(sockaddr*)&clientaddr,sizeof(clientaddr));
close(serversocket);}
Output
Department Of Computer Science BM II College Of Engineering, Sasthamcotta96
Network-OS Lab Manual
Client
Algorithm
* The different processes involved in a udp client process are........
1.Create a datagram socket.
2.Receive/Send message to the server.
3.Close the socket.
Program
/* Program to demonstrate the creation and usage of datagram sockets.
* This module acts as a udp client which sends and receives messages from a udp server.
* This module should be compiled into different folder using the command 'c++ udpclient.cpp -o b' and execute using './b'
* For execution the 'udpserver' module should be executed first then this module.
//inculsion.#include<iostream>#include<stdio.h>#include<sys/types.h>
Department Of Computer Science BM II College Of Engineering, Sasthamcotta97
Network-OS Lab Manual
#include<netinet/in.h>#include<netdb.h>
int main(){
//variable to store the socket_id. int clientsocket;
//variable to store the address. sockaddr_in serveraddr;
//variableto store the address length. socklen_t len;
//variable to store the network byte order address. hostent *server; char message[50];
//socket creation. clientsocket=socket(AF_INET,SOCK_DGRAM,0);
//steps involved in the server address creation. bzero((char*)&serveraddr,sizeof(serveraddr)); len=sizeof(serveraddr); serveraddr.sin_family=AF_INET; serveraddr.sin_port=htons(5015); server=gethostbyname("127.0.0.1"); bcopy((char*)server->h_addr,(char*)&serveraddr.sin_addr.s_addr,sizeof(server->h_addr)); printf("\nPRESS ENTER TO START THE CONNECTION PROCESS.\n"); fgets(message,2,stdin); printf("\nSending message for server connection\n");
//sending message. sendto(clientsocket,"HI I AM CLIENT...",sizeof("HI I AM CLIENT...."),0,(sockaddr*)&serveraddr,sizeof(serveraddr));
printf("\nReceiving message from server.\n");
//receiving messages. recvfrom(clientsocket,message,sizeof(message),0,(sockaddr*)&serveraddr,&len);
printf("\nMessage received:\t%s\n",message);
close(clientsocket);}
Output
Department Of Computer Science BM II College Of Engineering, Sasthamcotta98
Network-OS Lab Manual
Department Of Computer Science BM II College Of Engineering, Sasthamcotta99
Network-OS Lab Manual
MACPROTOCOLS
Theory
The Media Access Control (MAC) data communication protocol sub-layer, also
known as the Medium Access Control, is a part of the data link layer specified in the seven-
layer OSI model (layer 2). It provides addressing and channel access control mechanisms that
make it possible for several terminals or network nodes to communicate within a multipoint
network, typically a local area network (LAN) or metropolitan area network (MAN). A MAC
protocol is not required in full-duplex point-to-point communication. In single channel point-
to-point communications full-duplex can be emulated. This emulation can be considered a
MAC layer.
The MAC sub-layer acts as an interface between the Logical Link Control sublayer
and the network's physical layer.
The MAC layer provides an addressing mechanism called physical address or MAC
address. This is a unique serial number assigned to each network adapter, making it possible
to deliver data packets to a destination within a subnetwork, i.e. a physical network without
routers, for example an Ethernet network.
Media access control is often used as a synonym to multiple access protocol, since the MAC
sublayer provides the protocol and control mechanisms that are required for a certain channel
access method. This makes it possible for several stations connected to the same physical
medium to share it. Examples of shared physical medium are bus networks, ring networks,
hub networks, wireless networks and half-duplex point-to-point links.
SLIDING WINDOW PROTOCOL
Department Of Computer Science BM II College Of Engineering, Sasthamcotta100
Network-OS Lab Manual
In the simplex, stop and wait protocols, data frames were transmitted
in one direction only. In most practical solutions, there is a need for transmitting data in both
directions. One way of achieving full-duplex data transmission is to have two separate
communication channels and use each one for simplex data traffic. If this is done, we have
two separate physical circuits, each with a “forward” channel (for data) and a” reverse”
channel (for acknowledgements).In both cases the bandwidth of the reverse channel is almost
wasted.
A better idea is to use same circuit for data in both directions. In this model data
frames from A to B are intermixed with the acknowledgement frames from A to B.By
looking at the kind field in the header of an incoming frame, the receiver can tell whether the
frame is data or acknowledgement. When a data frame arrives, instead of immediately
sending a separate control frame, the receiver retrains itself and waits until the network layer
passes it the next packet. The acknowledgement is attached to the outgoing data frame. The
technique of temporarily delaying outgoing acknowledgements so that they can be hooked
onto the next outgoing data frame known as piggybacking. The principal advantage of using
piggybacking over having distinct acknowledgement frames is a better use of the available
channel bandwidth.
Bidirectional protocols that belongs to a class called sliding window
protocols. They differ among themselves in terms of efficincy, complexity,and buffer
requirements. All sliding window protocols ,each outbound frame contains a sequence
number ,ranging from 0 up to some maximum. The essence of all sliding window protocols
is that at any instant of time ,the sender maintains a set of sequence numbers corresponding
to frames it is permitted to send . These frames are said to fall within the sending window,
the receiver also maintains a receiving window corresponding to the set of frames it is
permitted to accept.
A One- Bit Sliding Window Protocol
A sliding window protocol with a maximum window size of 1.Such a
protocol uses a stop-and-wait since the sender transmits a frame and waits for its
acknowledgement before sending the next one. The starting machine fetches the first packet
Department Of Computer Science BM II College Of Engineering, Sasthamcotta101
Network-OS Lab Manual
from its network layer, builds a frame from it, and sends it. The acknowledgement field
contains the number of the last frame received without error. If this number agrees with the
sequence number of the frame the sender is trying to send ,the sender knows it is done with
the frame stored in buffer and can fetch the next packet from its network layer. If the
sequence number disagrees, it must continue trying to send the same frame Whenever a
frame is received, a frame also sent back.
A Protocol Using Go Back N
Two basic approaches are available for dealing with errors in the
presence of pipelining. One way, called go back n ,is for the receiver simply to discard all
subsequent frames ,sending no acknowledgements for the discarded frames. In other words,
the data link layer refuses to accept any frame except the next one it must give to the network
layer
A Protocol Using Selective Repeat
In this protocol, both sender and receiver maintain a window of acceptable
sequence numbers. The sender’s window size starts out at 0 and grows to some predefined
maximum. The receiver’s window, in contrast, is always fixed in size and equal to maximum.
The receiver has a buffer reserved for each sequence number within its fixed window.
Whenever a frame arrives, its sequence number is checked by the function between to see if
falls within the window. If so and if it has not already been received, it is accepted and
stroed.This action is taken without regard to whether or not it contains the next packet
expected by the network layer.
Department Of Computer Science BM II College Of Engineering, Sasthamcotta102
Network-OS Lab Manual
GOBACKN PROTOCOLS
Server
Algorithm
* The algorithm for this process is as............................
1. Start.
2. Establish connection (recommended UDP)
3. Accept the window size from the client(should be <=40)
4. Accept the packets from the network layer.
5. Calculate the total frames/windows required.
6. Send the details to the client(totalpackets,totalframes.)
7. Initialise the transmit buffer.
8. Built the frame/window depending on the windowsize.
9. Transmit the frame.
10. Wait for the acknowledgement frame.
11. Check for the acknowledgement of each packet and repeat the process
from the packet for which the first negative acknowledgement is
received.
Else continue as usual.
12. Increment the framecount and repeat steps 7 to 12 until all packets are
transmitted.
13. Close the connection.
14. Stop.
Department Of Computer Science BM II College Of Engineering, Sasthamcotta103
Network-OS Lab Manual
Program
/* Program to demonstrate the working of 'GO BACK N PROTOCOL'.
* This module act as a server which initially establishes a connection with the client,
sends packets to it (using sliding window protocol),receives acknowledgement and
retransmits the packets for which negative acknowledgement is received (using go
back n protocol).
* It uses an UDP connection for the whole process.
* It uses two structures viz. 'frame' to design the frames/window to be transmitted and
'ack' to accept the acknowledgement.
* Here -1 is referred to as negative acknowledgement while all the other integers as
positive acknwoledgement.
* The initial process are similar to that defined in the sliding window server process.
//inculsion#include<iostream>#include<stdio.h>
#include<sys/types.h>#include<netinet/in.h>#include<netdb.h>
#define cls() printf("\033[H\033[J")
//structure definition for designing the packet.struct frame{ int packet[40];};
//structure definition for accepting the acknowledgement.struct ack{ int acknowledge[40];};
int main(){
Department Of Computer Science BM II College Of Engineering, Sasthamcotta104
Network-OS Lab Manual
int serversocket; sockaddr_in serveraddr,clientaddr; socklen_t len; int windowsize,totalpackets,totalframes,framessend=0,i=0,j=0,k,buffer,l; ack acknowledgement; frame f1; char req[50];
serversocket=socket(AF_INET,SOCK_DGRAM,0);
bzero((char*)&serveraddr,sizeof(serveraddr)); serveraddr.sin_family=AF_INET; serveraddr.sin_port=htons(5018); serveraddr.sin_addr.s_addr=INADDR_ANY;
bind(serversocket,(sockaddr*)&serveraddr,sizeof(serveraddr));
bzero((char*)&clientaddr,sizeof(clientaddr)); len=sizeof(clientaddr);
//connection establishment. printf("\nWaiting for client connection.\n"); recvfrom(serversocket,req,sizeof(req),0,(sockaddr*)&clientaddr,&len); printf("\nThe client connection obtained.\t%s\n",req);
//sending request for windowsize. printf("\nSending request for window size.\n"); sendto(serversocket,"REQUEST FOR WINDOWSIZE.",sizeof("REQUEST FOR WINDOWSIZE."),0,(sockaddr*)&clientaddr,sizeof(clientaddr));
//obtaining windowsize. printf("\nWaiting for the windowsize.\n"); recvfrom(serversocket,(char*)&windowsize,sizeof(windowsize),0,(sockaddr*)&clientaddr,&len); cls(); printf("\nThe windowsize obtained as:\t%d\n",windowsize);
printf("\nObtaining packets from network layer.\n"); printf("\nTotal packets obtained:\t%d\n",(totalpackets=windowsize*5)); printf("\nTotal frames or windows to be transmitted:\t%d\n",(totalframes=5));
//sending details to client. printf("\nSending total number of packets.\n"); sendto(serversocket,(char*)&totalpackets,sizeof(totalpackets),0,(sockaddr*)&clientaddr,sizeof(clientaddr)); recvfrom(serversocket,req,sizeof(req),0,(sockaddr*)&clientaddr,&len);
Department Of Computer Science BM II College Of Engineering, Sasthamcotta105
Network-OS Lab Manual
printf("\nSending total number of frames.\n"); sendto(serversocket,(char*)&totalframes,sizeof(totalframes),0,(sockaddr*)&clientaddr,sizeof(clientaddr)); recvfrom(serversocket,req,sizeof(req),0,(sockaddr*)&clientaddr,&len); printf("\nPRESS ENTER TO START THE PROCESS.\n"); fgets(req,2,stdin); cls();
//starting the process of sending while( i<totalpackets) {
//initialising the transmit buffer. bzero((char*)&f1,sizeof(f1)); printf("\nInitialising the transmit buffer.\n"); printf("\nThe frame to be send is %d with packets:\t",framessend); buffer=i; j=0;
//Builting the frame. while(j<windowsize && i<totalpackets) { printf("%d ",i); f1.packet[j]=i; i++; j++; } printf("\nSending frame %d\n",framessend);
//sending the frame. sendto(serversocket,(char*)&f1,sizeof(f1),0,(sockaddr*)&clientaddr,sizeof(clientaddr));
//Waiting for the acknowledgement. printf("\nWaiting for the acknowledgement.\n"); recvfrom(serversocket,(char*)&acknowledgement,sizeof(acknowledgement),0,(sockaddr*)&clientaddr,&len); cls();
//Checking acknowledgement of each packet. j=0; k=0; l=buffer; while(j<windowsize && l<totalpackets) { if(acknowledgement.acknowledge[j]==-1) { printf("\nNegative acknowledgement received for packet: %d\n",f1.packet[j]);
Department Of Computer Science BM II College Of Engineering, Sasthamcotta106
Network-OS Lab Manual
printf("\nRetransmitting from packet: %d.\n",f1.packet[j]); i=f1.packet[j]; k=1; break; } j++; l++; }
if(k==0) { printf("\nPositive acknowledgement received for all packets within the frame: %d\n",framessend); }
framessend++; printf("\nPRESS ENTER TO PROCEED......\n"); fgets(req,2,stdin); cls(); }
printf("\nAll frames send successfully.\n\nClosing connection with the client.\n"); close(serversocket);}
Output
Department Of Computer Science BM II College Of Engineering, Sasthamcotta107
Network-OS Lab Manual
Client
Algorithm
* The algorithm for this module process is as........................
1. Start.
2. Establish a connection.(recommended UDP)
3. Send the windowsize on server request.
4. Accept the details from the server(totalpackets,totalframes).
5. Initialise the receive buffer with the expected packets.
6. Accept the frame/window from the server.
7. Check for validity of the packets and construct the acknowledgement
frame depending on the validity.(Here the acknowledgement is
accepeted from the users)
8. Depending on the acknowledgement frame readjust the process.
Department Of Computer Science BM II College Of Engineering, Sasthamcotta108
Network-OS Lab Manual
9. Increment the framecount and repeat steps 5-9 until all
packets are received.
10. Close the connection.
11. Stop.
Program
/* Program to demonstrate the working of 'GO BACK N PROTOCOL'.
* This module acts as a client which establishes a connection with the server, sends the
window size , accepts the frames and then sends acknowledgement for each packet
within the given frame.
* The connection used is UDP and the window size is taken from the user(should
be<=40)
* It uses two structures viz. 'frame' for accepting the frames send by the server and 'ack'
for sending the acknowledgement.
* Here the acknowledgement for each packet is accepted from the user. The user can
enter -1 for negative acknowledgement or any other integer for positive
acknowledgement.
* NOTE:-> This module can be compiled using the command 'c++ gobackn_server.cpp -o b'
and executed using the command './b'
Always compile and execute the server module first.
//inclusion.#include<iostream>#include<stdio.h>
#include<sys/types.h>#include<netinet/in.h>#include<netdb.h>
#define cls() printf("\033[H\033[J")
Department Of Computer Science BM II College Of Engineering, Sasthamcotta109
Network-OS Lab Manual
//structure definition for accepting the packets.struct frame{ int packet[40];};
//structure definition for constructing the acknowledgement framestruct ack{ int acknowledge[40];};
int main(){ int clientsocket; sockaddr_in serveraddr; socklen_t len; hostent * server; frame f1; int windowsize,totalpackets,totalframes,i=0,j=0,framesreceived=0,k,buffer,l; ack acknowledgement; char req[50];
clientsocket=socket(AF_INET,SOCK_DGRAM,0);
bzero((char*)&serveraddr,sizeof(serveraddr)); serveraddr.sin_family=AF_INET; serveraddr.sin_port=htons(5018); server=gethostbyname("127.0.0.1"); bcopy((char*)server->h_addr,(char*)&serveraddr.sin_addr.s_addr,sizeof(server->h_addr));
//establishing the connection. printf("\nSending request to the client.\n"); sendto(clientsocket,"HI I AM CLIENT.",sizeof("HI I AM CLIENT."),0,(sockaddr*)&serveraddr,sizeof(serveraddr));
printf("\nWaiting for reply.\n"); recvfrom(clientsocket,req,sizeof(req),0,(sockaddr*)&serveraddr,&len); printf("\nThe server has send:\t%s\n",req);
//accepting window size from the user. printf("\nEnter the window size:\t"); scanf("%d",&windowsize);
//sending the window size. printf("\n\nSending the window size.\n");
Department Of Computer Science BM II College Of Engineering, Sasthamcotta110
Network-OS Lab Manual
sendto(clientsocket,(char*)&windowsize,sizeof(windowsize),0,(sockaddr*)&serveraddr,sizeof(serveraddr)); cls();
//collecting details from server. printf("\nWaiting for the server response.\n"); recvfrom(clientsocket,(char*)&totalpackets,sizeof(totalpackets),0,(sockaddr*)&serveraddr,&len); printf("\nThe total packets are:\t%d\n",totalpackets); sendto(clientsocket,"RECEIVED.",sizeof("RECEIVED."),0,(sockaddr*)&serveraddr,sizeof(serveraddr));
recvfrom(clientsocket,(char*)&totalframes,sizeof(totalframes),0,(sockaddr*)&serveraddr,&len); printf("\nThe total frames/windows are:\t%d\n",totalframes); sendto(clientsocket,"RECEIVED.",sizeof("RECEIVED."),0,(sockaddr*)&serveraddr,sizeof(serveraddr));
//starting the process. printf("\nStarting the process of receiving.\n"); while(i<totalpackets) {
//initialising the receive buffer. printf("\nInitialising the receive buffer.\n"); printf("\nThe expected frame is %d with packets: ",framesreceived); j=0; buffer=i; while(j<windowsize && i<totalpackets) { printf("%d ",i); i++; j++; }
printf("\n\nWaiting for the frame.\n");//accepting the frame.
recvfrom(clientsocket,(char*)&f1,sizeof(f1),0,(sockaddr*)&serveraddr,&len); printf("\nReceived frame %d\n\nEnter -1 to send negative acknowledgement for the following packets.\n",framesreceived);
//constructing the acknowledgement frame. j=0; l=buffer; k=0; while(j<windowsize && l<totalpackets) {
Department Of Computer Science BM II College Of Engineering, Sasthamcotta111
Network-OS Lab Manual
printf("\nPacket: %d\n",f1.packet[j]); //accepting acknowledgement from the user.
scanf("%d",&acknowledgement.acknowledge[j]);
if(acknowledgement.acknowledge[j]==-1) { if(k==0) { i=f1.packet[j]; k=1; } } j++; l++; } framesreceived++;
//sending acknowledgement to the server. sendto(clientsocket,(char*)&acknowledgement,sizeof(acknowledgement),0,(sockaddr*)&serveraddr,sizeof(serveraddr)); cls(); }
printf("\nAll frames received successfully.\n\nClosing connection with the server.\n"); close(clientsocket);}
Output
Department Of Computer Science BM II College Of Engineering, Sasthamcotta112
Network-OS Lab Manual
Department Of Computer Science BM II College Of Engineering, Sasthamcotta113
Network-OS Lab Manual
SELECTIVE REPEAT REQUEST PROTOCOL
Server
Algorithm
* The algorithm for this process is as............................
1. Start.
2. Establish connection (recommended UDP)
3. Accept the window size from the client(should be <=40)
4. Accept the packets from the network layer.
5. Calculate the total frames/windows required.
6. Send the details to the client(totalpackets,totalframes.)
7. Initialise the transmit buffer.
8. Built the frame/window depending on the windowsize.
Department Of Computer Science BM II College Of Engineering, Sasthamcotta114
Network-OS Lab Manual
9. Transmit the frame.
10. Wait for the acknowledgement frame.
11. Check for the acknowledgement of each packet and repeat the
process for the packet for which the negative acknowledgement isreceived.
Else continue as usual.
12. Increment the frame count and repeat steps 7 to 12 until all packets are
transmitted.
13. Close the connection.
14.Stop.
Program
/* Program to demonstrate the working of 'SELECTIVE REPEAT PROTOCOL'.
* This module act as a server which initially establishes a connection with the client, sends
packets to it (using sliding window protocol),receives acknowledgement and retransmits
the packets for which negative acknowledgement is received (using selective repeat
protocol).
* It uses an UDP connection for the whole process.
* It uses two structures viz. 'frame' to design the frames/window to be transmitted and
'ack' to accept the acknowledgement.
* Here -1 is referred to as negative acknowledgement while all the other integers as
positive acknowledgement.
* The initial process are similar to that defined in the sliding window server process.
* NOTE: -> This module can be compiled using the command 'c++
selectiverepeat_server.cpp' and executed using './a.out'
-> The server module should be compiled and executed first.
Department Of Computer Science BM II College Of Engineering, Sasthamcotta115
Network-OS Lab Manual
//inculsion#include<iostream>#include<stdio.h>
#include<sys/types.h>#include<netinet/in.h>#include<netdb.h>
#define cls() printf("\033[H\033[J")
//structure definition for designing the packet.struct frame{ int packet[40];};
//structure definition for accepting the acknowledgement.struct ack{ int acknowledge[40];};
int main(){ int serversocket; sockaddr_in serveraddr,clientaddr; socklen_t len; int windowsize,totalpackets,totalframes,framessend=0,i=0,j=0,k,l,m,n,repacket[40]; ack acknowledgement; frame f1; char req[50];
serversocket=socket(AF_INET,SOCK_DGRAM,0);
bzero((char*)&serveraddr,sizeof(serveraddr)); serveraddr.sin_family=AF_INET; serveraddr.sin_port=htons(5018); serveraddr.sin_addr.s_addr=INADDR_ANY;
bind(serversocket,(sockaddr*)&serveraddr,sizeof(serveraddr));
bzero((char*)&clientaddr,sizeof(clientaddr));
Department Of Computer Science BM II College Of Engineering, Sasthamcotta116
Network-OS Lab Manual
len=sizeof(clientaddr);
//connection establishment. printf("\nWaiting for client connection.\n"); recvfrom(serversocket,req,sizeof(req),0,(sockaddr*)&clientaddr,&len); printf("\nThe client connection obtained.\t%s\n",req);
//sending request for windowsize. printf("\nSending request for window size.\n"); sendto(serversocket,"REQUEST FOR WINDOWSIZE.",sizeof("REQUEST FOR WINDOWSIZE."),0,(sockaddr*)&clientaddr,sizeof(clientaddr));
//obtaining windowsize. printf("\nWaiting for the windowsize.\n"); recvfrom(serversocket,(char*)&windowsize,sizeof(windowsize),0,(sockaddr*)&clientaddr,&len); cls(); printf("\nThe windowsize obtained as:\t%d\n",windowsize);
printf("\nObtaining packets from network layer.\n"); printf("\nTotal packets obtained:\t%d\n",(totalpackets=windowsize*5)); printf("\nTotal frames or windows to be transmitted:\t%d\n",(totalframes=5));
//sending details to client. printf("\nSending total number of packets.\n"); sendto(serversocket,(char*)&totalpackets,sizeof(totalpackets),0,(sockaddr*)&clientaddr,sizeof(clientaddr)); recvfrom(serversocket,req,sizeof(req),0,(sockaddr*)&clientaddr,&len); printf("\nSending total number of frames.\n"); sendto(serversocket,(char*)&totalframes,sizeof(totalframes),0,(sockaddr*)&clientaddr,sizeof(clientaddr)); recvfrom(serversocket,req,sizeof(req),0,(sockaddr*)&clientaddr,&len); printf("\nPRESS ENTER TO START THE PROCESS.\n"); fgets(req,2,stdin); cls();
j=0; l=0; //starting the process of sending while( l<totalpackets) {
//initialising the transmit buffer. bzero((char*)&f1,sizeof(f1)); printf("\nInitialising the transmit buffer.\n"); printf("\nThe frame to be send is %d with packets:\t",framessend);
//Builting the frame.
Department Of Computer Science BM II College Of Engineering, Sasthamcotta117
Network-OS Lab Manual
for(m=0;m<j;m++) {
//including the packets for which negative acknowledgement was received. printf("%d ",repacket[m]); f1.packet[m]=repacket[m]; }
while(j<windowsize && i<totalpackets) { printf("%d ",i); f1.packet[j]=i; i++; j++; } printf("\nSending frame %d\n",framessend);
//sending the frame. sendto(serversocket,(char*)&f1,sizeof(f1),0,(sockaddr*)&clientaddr,sizeof(clientaddr));
//Waiting for the acknowledgement. printf("\nWaiting for the acknowledgement.\n"); recvfrom(serversocket,(char*)&acknowledgement,sizeof(acknowledgement),0,(sockaddr*)&clientaddr,&len); cls();
//Checking acknowledgement of each packet. j=0; k=0; m=0; n=l; while(m<windowsize && n<totalpackets) { if(acknowledgement.acknowledge[m]==-1) { printf("\nNegative acknowledgement received for packet: %d\n",f1.packet[m]); k=1; repacket[j]=f1.packet[m]; j++; } else { l++; } m++; n++; }
if(k==0)
Department Of Computer Science BM II College Of Engineering, Sasthamcotta118
Network-OS Lab Manual
{ printf("\nPositive acknowledgement received for all packets within the frame: %d\n",framessend); }
framessend++; printf("\nPRESS ENTER TO PROCEED......\n"); fgets(req,2,stdin); cls(); }
printf("\nAll frames send successfully.\n\nClosing connection with the client.\n"); close(serversocket);}
Output
Department Of Computer Science BM II College Of Engineering, Sasthamcotta119
Network-OS Lab Manual
Client
Algorithm
* The algorithm for this module process is as........................
1. Start.
2. Establish a connection.(recommended UDP)
3. Send the windowsize on server request.
4. Accept the details from the server(totalpackets,totalframes).
5. Initialise the receive buffer with the expected packets.
6. Accept the frame/window from the server.
7. Check for validity of the packets and construct the acknowledgement frame
depending on the validity.(Here the acknowledgement is accepeted from the
users)
Department Of Computer Science BM II College Of Engineering, Sasthamcotta120
Network-OS Lab Manual
8. Depending on the acknowledgement frame readjust the process.
9. Increment the framecount and repeat steps 5-9 until all packets are received.
10. Close the connection.
11. Stop.
Program
/* Program to demonstrate the working of 'SELECTIVE REPEAT PROTOCOL'.
* This module acts as a client which establishes a connection with the server, sends the
windowsize, accepts the frames and then sends acknowledgement for each packet wihin
the given frame.
* The connection used is UDP and the window size is taken from the user(should be<=40)
* It uses two structures viz. 'frame' for accepting the frames send by the server and 'ack' for
sending the acknowledgement.
* Here the acknowledgement for each packet is accepted from the user. The user can enter -1
for negative acknowledgement or any other integer for positive acknowledgement.
* NOTE: This module can be compiled using the command 'c++ selectiverepeat_server.cpp –
o b' and executed using the command './b'
-> Always compile and execute the server module first.
//inculsion.#include<iostream>#include<stdio.h>
#include<sys/types.h>#include<netinet/in.h>#include<netdb.h>
#define cls() printf("\033[H\033[J")
//structure definition for accepting the packets.struct frame{ int packet[40];
Department Of Computer Science BM II College Of Engineering, Sasthamcotta121
Network-OS Lab Manual
};
//structure definition for constructing the acknowledgement framestruct ack{ int acknowledge[40];};
int main(){ int clientsocket; sockaddr_in serveraddr; socklen_t len; hostent * server; frame f1; int windowsize,totalpackets,totalframes,i=0,j=0,framesreceived=0,k,l,m,repacket[40]; ack acknowledgement; char req[50];
clientsocket=socket(AF_INET,SOCK_DGRAM,0);
bzero((char*)&serveraddr,sizeof(serveraddr)); serveraddr.sin_family=AF_INET; serveraddr.sin_port=htons(5018); server=gethostbyname("127.0.0.1"); bcopy((char*)server->h_addr,(char*)&serveraddr.sin_addr.s_addr,sizeof(server->h_addr));
//establishing the connection. printf("\nSending request to the client.\n"); sendto(clientsocket,"HI I AM CLIENT.",sizeof("HI I AM CLIENT."),0,(sockaddr*)&serveraddr,sizeof(serveraddr));
printf("\nWaiting for reply.\n"); recvfrom(clientsocket,req,sizeof(req),0,(sockaddr*)&serveraddr,&len); printf("\nThe server has send:\t%s\n",req);
//accepting window size from the user. printf("\nEnter the window size:\t"); scanf("%d",&windowsize);
//sending the window size. printf("\n\nSending the window size.\n"); sendto(clientsocket,(char*)&windowsize,sizeof(windowsize),0,(sockaddr*)&serveraddr,sizeof(serveraddr)); cls();
Department Of Computer Science BM II College Of Engineering, Sasthamcotta122
Network-OS Lab Manual
//collecting details from server. printf("\nWaiting for the server response.\n"); recvfrom(clientsocket,(char*)&totalpackets,sizeof(totalpackets),0,(sockaddr*)&serveraddr,&len); printf("\nThe total packets are:\t%d\n",totalpackets); sendto(clientsocket,"RECEIVED.",sizeof("RECEIVED."),0,(sockaddr*)&serveraddr,sizeof(serveraddr));
recvfrom(clientsocket,(char*)&totalframes,sizeof(totalframes),0,(sockaddr*)&serveraddr,&len); printf("\nThe total frames/windows are:\t%d\n",totalframes); sendto(clientsocket,"RECEIVED.",sizeof("RECEIVED."),0,(sockaddr*)&serveraddr,sizeof(serveraddr));
//starting the process. printf("\nStarting the process of receiving.\n"); j=0; l=0; while(l<totalpackets) {
//initialising the receive buffer. printf("\nInitialising the receive buffer.\n"); printf("\nThe expected frame is %d with packets: ",framesreceived); for(m=0;m<j;m++) {
//readjusting for packets with negative acknowledgement. printf("%d ",repacket[m]); } while(j<windowsize && i<totalpackets) { printf("%d ",i); i++; j++; }
printf("\n\nWaiting for the frame.\n");//accepting the frame.
recvfrom(clientsocket,(char*)&f1,sizeof(f1),0,(sockaddr*)&serveraddr,&len); printf("\nReceived frame %d\n\nEnter -1 to send negative acknowledgement for the following packets.\n",framesreceived);
//constructing the acknowledgement frame. j=0; m=0; k=l;
Department Of Computer Science BM II College Of Engineering, Sasthamcotta123
Network-OS Lab Manual
while(m<windowsize && k<totalpackets) { printf("\nPacket: %d\n",f1.packet[m]);
//accepting acknowledgement from the user. scanf("%d",&acknowledgement.acknowledge[m]);
if(acknowledgement.acknowledge[m]==-1) { repacket[j]=f1.packet[m]; j++; } else { l++; } m++; k++; } framesreceived++;
//sending acknowledgement to the server. sendto(clientsocket,(char*)&acknowledgement,sizeof(acknowledgement),0,(sockaddr*)&serveraddr,sizeof(serveraddr)); cls(); }
printf("\nAll frames received successfully.\n\nClosing connection with the server.\n"); close(clientsocket);}
Output
Department Of Computer Science BM II College Of Engineering, Sasthamcotta124
Network-OS Lab Manual
SLIDING WINDOW PROTOCOL
Department Of Computer Science BM II College Of Engineering, Sasthamcotta125
Network-OS Lab Manual
Server
Algorithm
* The algorithm for the sliding window server is as..........
1.Start
2.Establish connection with the client.(UDP/TCP recommended UDP)
3.Accept the window size from the client.
4.Accept the packets from the network layer.
5.Combine packets to form frame/window.(depending on window size.)
6.Initialise the transmit buffer.
7.Send the frame and wait for the acknowledgement.
8.If a negative acknowledgement is received repeat the transmission of the
previous frame.
Else increment the frame to be transmitted.
9.Repeat steps 5 to 8 until all packet are transmitted successfully.
10.Close the connection.
11.Stop.
Program
/* Program to demonstrate the working of 'SLIDING WINDOW PROTOCOL'
* This module act as a server module which transmits the packets to the client.
* The server initially establishes connection with the client then accepts the window
size(should be always<=40).
* Then it calculates the total no. of packets by multiplying the window size with 5
(assumption: totalpackets=windowsize*5).
* Then frames are prepared depending upon the window size,transmits it to the client and
waits for the acknowledgement.
* If a negative (-1) acknowledgement is received the frame is transmitted again, else the next
Department Of Computer Science BM II College Of Engineering, Sasthamcotta126
Network-OS Lab Manual
frame is transmitted.
NOTE: Here only a single acknowledgement is considered for all the packets within a given
frame.
*NOTE: -> Compile this module using the command 'c++
slidingwindowserver.cpp'. To execute use './a.out'.
-> Compile and execute the server module first.
//inclusion.#include<iostream>#include<stdio.h>
#include<sys/types.h>#include<netinet/in.h>#include<netdb.h>
#define cls() printf("\033[H\033[J")
//structure definition for defining the frame.struct frame{ int packet[40];};
int main(){ int serversocket; sockaddr_in serveraddr,clientaddr; socklen_t len; int windowsize,totalpackets,totalframes,framessend=0,i=0,j=0,buffer,acknowledgement; frame f1; char req[50];
serversocket=socket(AF_INET,SOCK_DGRAM,0);
bzero((char*)&serveraddr,sizeof(serveraddr)); serveraddr.sin_family=AF_INET; serveraddr.sin_port=htons(5016); serveraddr.sin_addr.s_addr=INADDR_ANY;
bind(serversocket,(sockaddr*)&serveraddr,sizeof(serveraddr));
bzero((char*)&clientaddr,sizeof(clientaddr)); len=sizeof(clientaddr);
Department Of Computer Science BM II College Of Engineering, Sasthamcotta127
Network-OS Lab Manual
//connection establishment. printf("\nWaiting for client connection.\n"); recvfrom(serversocket,req,sizeof(req),0,(sockaddr*)&clientaddr,&len); printf("\nThe client connection obtained.\t%s\n",req);
//sending request for windowsize. printf("\nSending request for window size.\n"); sendto(serversocket,"REQUEST FOR WINDOWSIZE.",sizeof("REQUEST FOR WINDOWSIZE."),0,(sockaddr*)&clientaddr,sizeof(clientaddr));
//obtaining windowsize. printf("\nWaiting for the windowsize.\n"); recvfrom(serversocket,(char*)&windowsize,sizeof(windowsize),0,(sockaddr*)&clientaddr,&len); cls(); printf("\nThe windowsize obtained as:\t%d\n",windowsize);
printf("\nObtaining packets from network layer.\n"); printf("\nTotal packets obtained:\t%d\n",(totalpackets=windowsize*5)); printf("\nTotal frames or windows to be transmitted:\t%d\n",(totalframes=5));
//sending details to client. printf("\nSending total number of packets.\n"); sendto(serversocket,(char*)&totalpackets,sizeof(totalpackets),0,(sockaddr*)&clientaddr,sizeof(clientaddr)); recvfrom(serversocket,req,sizeof(req),0,(sockaddr*)&clientaddr,&len); printf("\nSending total number of frames.\n"); sendto(serversocket,(char*)&totalframes,sizeof(totalframes),0,(sockaddr*)&clientaddr,sizeof(clientaddr)); recvfrom(serversocket,req,sizeof(req),0,(sockaddr*)&clientaddr,&len); printf("\nPRESS ENTER TO START THE PROCESS.\n"); fgets(req,2,stdin); cls();
//starting the process of sending while(framessend<totalframes) { printf("\nInitialising the transmit buffer.\n"); printf("\nThe frame to be send is %d with packets:\t",framessend); j=0; buffer=i;
//preparing the frame. while(j<windowsize && i<totalpackets) {
Department Of Computer Science BM II College Of Engineering, Sasthamcotta128
Network-OS Lab Manual
printf("%d ",i); f1.packet[j]=i; i++; j++; } printf("\nSending frame %d\n",framessend);
//sending frame. sendto(serversocket,(char*)&f1,sizeof(f1),0,(sockaddr*)&clientaddr,sizeof(clientaddr)); printf("\nWaiting for the acknowledgement.\n");
//waiting for the acknowledgement. recvfrom(serversocket,(char*)&acknowledgement,sizeof(int),0,(sockaddr*)&clientaddr,&len); cls();
//cheching the acknowledgement. if(acknowledgement==-1) { printf("\nNegative acknowledgement received for frame %d\n",framessend); printf("\nRetransmitting the frame.\n"); i=buffer; }
else { printf("\nPositive acknowledgement received for frame %d.\n",framessend); framessend++; } printf("\nPRESS ENTER TO PROCEED......\n"); fgets(req,2,stdin); cls(); }
printf("\nAll frames send successfully.\n\nClosing connection with the client.\n"); close(serversocket);}
Output
Department Of Computer Science BM II College Of Engineering, Sasthamcotta129
Network-OS Lab Manual
Client
Algorithm
Department Of Computer Science BM II College Of Engineering, Sasthamcotta130
Network-OS Lab Manual
* The algorithm for the client process is as............
1.Start.
2.Establish a connection with the server.(recommended UDP.)
3.Send the window size on server request.
4.Accept the details from the server.(totalpackets,totalframes.)
5.Initialise the receive buffer with the expected frame and packets.
6.Accept the frame and check for its validity.
7.Send positive or negative acknowledgement as required.
8.Repeat steps 5 to 7 until all packets are received.
9.Close the connection with the server.
10.Stop.
Program
/* Program to demonstrate the working of 'SLIDING WINDOW PROTOCOL.'
* This module act as client which accepts the packets from the server.
* The client initially establishes a connection with the server and then on request from the server sends the window size to the server.
NOTE: Here the window size is taken from the user. The user can input any valid number <=40.
* It also collects details such as the total packets and total frames from the server.
* It then receives the frames from the server for which it sends acknowledgement.
NOTE: Here the acknowledgement is accepted from the user. The user can input -1 for negative acknowledgement and 1 or any other number for positive acknowledgement.
//inculsion#include<iostream>#include<stdio.h>
Department Of Computer Science BM II College Of Engineering, Sasthamcotta131
Network-OS Lab Manual
#include<sys/types.h>#include<netinet/in.h>#include<netdb.h>#define cls() printf("\033[H\033[J")
//structure definition for accepting the frame.struct frame{ int packet[40];};
int main(){ int clientsocket; sockaddr_in serveraddr; socklen_t len; hostent * server; frame f1; int windowsize,totalpackets,totalframes,i=0,j=0,framesreceived=0,acknowledgement,buffer; char req[50];
clientsocket=socket(AF_INET,SOCK_DGRAM,0);
bzero((char*)&serveraddr,sizeof(serveraddr)); serveraddr.sin_family=AF_INET; serveraddr.sin_port=htons(5016); server=gethostbyname("127.0.0.1"); bcopy((char*)server->h_addr,(char*)&serveraddr.sin_addr.s_addr,sizeof(server->h_addr));
printf("\nSending request to the client.\n"); sendto(clientsocket,"HI I AM CLIENT.",sizeof("HI I AM CLIENT."),0,(sockaddr*)&serveraddr,sizeof(serveraddr));
//accepting the window request. printf("\nWaiting for reply.\n"); recvfrom(clientsocket,req,sizeof(req),0,(sockaddr*)&serveraddr,&len); printf("\nThe server has send:\t%s\n",req);
//taking the window size from the user. printf("\nEnter the window size:\t"); scanf("%d",&windowsize);
//sending the window size. printf("\n\nSending the window size.\n"); sendto(clientsocket,(char*)&windowsize,sizeof(windowsize),0,(sockaddr*)&serveraddr,sizeof(serveraddr));
Department Of Computer Science BM II College Of Engineering, Sasthamcotta132
Network-OS Lab Manual
cls();
//collecting details from server. printf("\nWaiting for the server response.\n"); recvfrom(clientsocket,(char*)&totalpackets,sizeof(totalpackets),0,(sockaddr*)&serveraddr,&len); printf("\nThe total packets are:\t%d\n",totalpackets); sendto(clientsocket,"RECEIVED.",sizeof("RECEIVED."),0,(sockaddr*)&serveraddr,sizeof(serveraddr));
recvfrom(clientsocket,(char*)&totalframes,sizeof(totalframes),0,(sockaddr*)&serveraddr,&len); printf("\nThe total frames/windows are:\t%d\n",totalframes); sendto(clientsocket,"RECEIVED.",sizeof("RECEIVED."),0,(sockaddr*)&serveraddr,sizeof(serveraddr));
//starting the process. printf("\nStarting the process of receiving.\n"); while(framesreceived<totalframes) {
//initialising the receive buffer. printf("\nInitialising the receive buffer.\n"); printf("\nThe expected frame is %d with packets: ",framesreceived); j=0; buffer=i; while(j<windowsize && i<totalpackets) { printf("%d ",i); i++; j++; }
printf("\n\nWaiting for the frame.\n");
//receiving the frame. recvfrom(clientsocket,(char*)&f1,sizeof(f1),0,(sockaddr*)&serveraddr,&len); printf("\nReceived frame %d\n\nEnter -1 to send negative acknowledgement\n",framesreceived);
//taking acknowledgement from the user. scanf("%d",&acknowledgement); if(acknowledgement==-1) { i=buffer; } else {
Department Of Computer Science BM II College Of Engineering, Sasthamcotta133
Network-OS Lab Manual
framesreceived++; }
//sending acknowledgement to the server. sendto(clientsocket,(char*)&acknowledgement,sizeof(int),0,(sockaddr*)&serveraddr,sizeof(serveraddr)); cls(); }
printf("\nAll frames received successfully.\n\nClosing connection with the server.\n"); close(clientsocket);}
Output
Department Of Computer Science BM II College Of Engineering, Sasthamcotta134
Network-OS Lab Manual
FILE TRANSFER PROTOCOL
Theory
Department Of Computer Science BM II College Of Engineering, Sasthamcotta135
Network-OS Lab Manual
The FTP protocol is used to access files by FTP, the internet”s file transfer protocol.
Ftp has been around more than two decades and is well entrenched. Numerous FTP servers
all over the world allow people anywhere on the internet to log in and download whatever
files have been placed on the FTP server. The Web does not change this; it just makes
obtaining files by FTP easier, as FTP has a somewhat arcane interface.
It is possible to access a local file as a web page, either by using the file protocol or
more simply by just naming it. This approach is similar to using FTP but does not require
having a server. Of course, it works only for files not remote ones.
Server
Algorithm
* The algorithm for ftp server can be summerised as...................
1. Start.
2. Establish a tcp socket.
3. Listen over the socket.
4. Accept a connection.
5. Obtain the filename from the client.
6. Read the file.
7. Send it to the client.
8. Close the connection.
9. Stop.
Program
/* Program to demonstrate the implementation of ftp protocol.
* This module act as a ftp module, which accepts the filename, reads the file and sends it to
Department Of Computer Science BM II College Of Engineering, Sasthamcotta136
Network-OS Lab Manual
the client.
* This module establishes a tcp connection with the client.
* NOTE:
1. The file to be transfered should be in the same directory where this module is stored.
2. If the file does not exist the program might terminate abnormally.
3. The error handling routine has not been provided. It is assumed that everything would be
perfect.
* This program can be compiled using 'c++ simpleftpserver.cpp' and executed './a.out'
//inculsion.#include<iostream>#include<stdio.h>#include<string.h>
#include<sys/types.h>#include<netinet/in.h>#include<netdb.h>
int main(){ int serversocket,clientsocket; sockaddr_in serveraddr,clientaddr; socklen_t len; FILE *ptr; char filename[20]; char file[2048],temp[500];
bzero(filename,sizeof(filename)); bzero(file,sizeof(file));
serversocket=socket(AF_INET,SOCK_STREAM,0);
bzero((char*)&serveraddr,sizeof(serveraddr)); serveraddr.sin_family=AF_INET; serveraddr.sin_port=htons(5015); serveraddr.sin_addr.s_addr=INADDR_ANY;
bind(serversocket,(sockaddr*)&serveraddr,sizeof(serveraddr));
bzero((char*)&clientaddr,sizeof(clientaddr));
Department Of Computer Science BM II College Of Engineering, Sasthamcotta137
Network-OS Lab Manual
len=sizeof(clientaddr);
listen(serversocket,5); printf("\nWaiting for the connection\n"); clientsocket=accept(serversocket,(sockaddr*)&clientaddr,&len); printf("\nConnection obtained.\n");
read(clientsocket,filename,sizeof(filename));
printf("\nThe read filename is:\t%s\n",filename); printf("\nReading the file.\n");
ptr=fopen(filename,"r"); while(fgets(temp,sizeof(temp),ptr)!=NULL) { strcat(file,temp); } fclose(ptr);
printf("\nSending the file.\n"); write(clientsocket,file,sizeof(file));
close(clientsocket); close(serversocket);}
Output
Department Of Computer Science BM II College Of Engineering, Sasthamcotta138
Network-OS Lab Manual
Client
Algorithm
* The algorithm for the process can be summerised as...............
1. Start.
2. Establish a tcp connection.
3. Connect to the ftp server.
4. Send the filename.
5. Read the filecontents.
6. Create a file as required.
7. Close the connection.
8. Stop.
Program
/* Program to demonstrate the implementation of ftp protocol.
* This module act as the ftp client which sends the filename and receives the file from the
server.
* This module is designed with a view to represent the ftp process with simplicity, so it only
sends and receives data.
Department Of Computer Science BM II College Of Engineering, Sasthamcotta139
Network-OS Lab Manual
* It can be compiled using 'c++ simpleftpclient.cpp -o b' and executed './b'
#include<iostream>#include<stdio.h>
#include<sys/types.h>#include<netinet/in.h>#include<netdb.h>
#define FILENAME "sample.c"
int main(){ int clientsocket; sockaddr_in serveraddr; hostent * server; FILE * ptr; char file[2048];
bzero(file,sizeof(file));
clientsocket=socket(AF_INET,SOCK_STREAM,0);
bzero((char*)&serveraddr,sizeof(serveraddr));
serveraddr.sin_family=AF_INET; serveraddr.sin_port=htons(5015); server=gethostbyname("127.0.0.1"); bcopy((char*)server->h_addr,(char*)&serveraddr.sin_addr.s_addr,sizeof(server->h_addr));
printf("\nTrying to connect to the server.\n"); connect(clientsocket,(sockaddr*)&serveraddr,sizeof(serveraddr)); printf("\nConnected to the server.\n");
write(clientsocket,FILENAME,sizeof(FILENAME)); printf("\nSending filename.\n");
read(clientsocket,file,sizeof(file));
printf("\nThe file is:\n%s",file); ptr=fopen(FILENAME,"w"); fprintf(ptr,"%s",file); fclose(ptr); close(clientsocket);}
Department Of Computer Science BM II College Of Engineering, Sasthamcotta140
Network-OS Lab Manual
Output
Department Of Computer Science BM II College Of Engineering, Sasthamcotta141
Network-OS Lab Manual
SIMPLE MAIL TRANSFER PROTOCOL
Theory
SMTP is a relatively simple, text-based protocol, where one or more recipients of a
message are specified (and in most cases verified to exist) and then the message text is
transferred. It is a client-server protocol, where the client transmits an email message to the
server. Either an end-user's email client, a.k.a. MUA (Mail User Agent), or a relaying server's
MTA (Mail Transfer Agents) can act as an SMTP client.
An email client knows the outgoing mail SMTP server from its configuration. A
relaying server typically determines which SMTP server to connect to by looking up the MX
(Mail eXchange) DNS record for each recipient's domain name (the part of the email address
to the right of the at (@) sign). Conformant MTAs (not all) fall back to a simple A record in
the case of no MX. Some current mail transfer agents will also use SRV records, a more
general form of MX, though these are not widely adopted. (Relaying servers can also be
configured to use a smart host.)
The SMTP client initiates a TCP connection to server's port 25 (unless overridden by
configuration). It is quite easy to test an SMTP server using the telnet program (see below).
SMTP is a "push" protocol that does not allow one to "pull" messages from a remote
server on demand. To do this a mail client must use POP3 or IMAP. Another SMTP server
can trigger a delivery in SMTP using ETRN
Department Of Computer Science BM II College Of Engineering, Sasthamcotta142
Network-OS Lab Manual
Server
Algorithm
* The different steps involved in the process are..........
1. Start the process.
2. Establish an UDP connection and wait for request.
3. Accept SMTP REQUEST from the client and send replyas 220:SERVICE READY.
4. Accept HELO REQUEST for which send reply as 250:REQUEST COMMAND
COMPLETED.
5. Accept MAIL TO: command for which send reply as 250:REQUEST COMMAND
COMPLETED.
6. Accept RCPT TO: command for which send reply as 250:REQUEST COMMAND
COMPLETED.
7 .Accept DATA: command for which send reply as 354:START MAIL INPUT.
8. Accept the mail contents,search for the correspondin recipient server and transmit mail to
it.
9 .If transmission is successful send reply as 250:REQUEST COMMAND COMPLETED.
10. Accept QUIT: command from the client for which send reply 221:SERVICE CLOSING.
11. Close the connection.
12. Stop.
Program
/* Program to demonstrate the working of smtp protocol..............
* This program module acts as SMTP server which accepts the mail from the client and then
sends(acts as sending) it to the corresponding recipient server.
* This module establishes a UDP connection with the client and uses it for sending the
corresponding commands.
* NOTE: This module just immitate as a SMTP server.
Department Of Computer Science BM II College Of Engineering, Sasthamcotta143
Network-OS Lab Manual
* Compile this module as usual and execute it using the command './a.out'
//inculsion#include<iostream>#include<stdio.h>#include<string.h>
#include<sys/types.h>#include<netinet/in.h>#include<netdb.h>
#define cls() printf("\033[H\033[J");
int main(){ int serversocket; sockaddr_in serveraddr,clientaddr; socklen_t len; char request[50]; char from[50]; char to[50]; char mail[100];
serversocket=socket(AF_INET,SOCK_DGRAM,0);
bzero((char*)&serveraddr,sizeof(serveraddr));
serveraddr.sin_family=AF_INET; serveraddr.sin_port=htons(5015); serveraddr.sin_addr.s_addr=INADDR_ANY;
bind(serversocket,(sockaddr*)&serveraddr,sizeof(serveraddr));
bzero((char*)&clientaddr,sizeof(clientaddr)); len=sizeof(clientaddr); cls();
//waiting for the request. printf("\nWaiting for the request from the client.\n"); recvfrom(serversocket,request,sizeof(request),0,(sockaddr*)&clientaddr,&len); printf("The request received is:\t%s",request);
printf("\nPRESS ENTER TO SEND THE RESPONSE.\n"); fgets(request,2,stdin);
Department Of Computer Science BM II College Of Engineering, Sasthamcotta144
Network-OS Lab Manual
printf("\nSending the 220:SERVICE READY COMMAND.\n"); strcpy(request,"220:SERVICE READY."); sendto(serversocket,request,sizeof(request),0,(sockaddr*)&clientaddr,len);
//waiting for the first command
printf("Waiting for the next request."); recvfrom(serversocket,request,sizeof(request),0,(sockaddr*)&clientaddr,&len); cls(); printf("\nThe client has send:\t%s\n",request);
printf("\nPRESS ENTER TO SEND THE RESPONSE.\n"); fgets(request,2,stdin); printf("\nSending the POSITIVE COMPLETION REPLY:250 REQUEST COMMAND COMPLETED.\n"); strcpy(request,"250:REQUEST COMMAND COMPLETED."); sendto(serversocket,request,sizeof(request),0,(sockaddr*)&clientaddr,sizeof(clientaddr));
//waiting for second command. printf("\nWaiting for the next request.\n"); recvfrom(serversocket,request,sizeof(request),0,(sockaddr*)&clientaddr,&len); cls(); printf("\nThe client has send:\t%s\n",request); strcpy(from,request);
printf("\nPRESS ENTER TO SEND THE RESPONSE.\n"); fgets(request,2,stdin); printf("\nSending the POSITIVE COMPLETION REPLY:250\n"); strcpy(request,"250:REQUEST COMMAND COMPLETED."); sendto(serversocket,request,sizeof(request),0,(sockaddr*)&clientaddr,sizeof(clientaddr));
//waiting for the third command. printf("\nWaiting for the next request.\n"); recvfrom(serversocket,request,sizeof(request),0,(sockaddr*)&clientaddr,&len); cls(); printf("\nThe client has send:\t%s\n",request); strcpy(to,request);
printf("\nPRESS ENTER TO SEND THE RESPONSE.\n"); fgets(request,2,stdin); printf("\nSending the POSITIVE COMPLETION REPLY:250\n"); strcpy(request,"250:REQUEST COMMAND COMPLETED."); sendto(serversocket,request,sizeof(request),0,(sockaddr*)&clientaddr,sizeof(clientaddr));
//waiting for the fourth command. printf("\nWaiting for the next request.\n");
Department Of Computer Science BM II College Of Engineering, Sasthamcotta145
Network-OS Lab Manual
recvfrom(serversocket,request,sizeof(request),0,(sockaddr*)&clientaddr,&len); cls(); printf("\nThe client has send:\t%s\n",request);
printf("\nPRESS ENTER TO SEND THE RESPONSE.\n"); fgets(request,2,stdin); printf("\nSending the 354:START MAIL INPUT.\n"); strcpy(request,"354:START MAIL INPUT."); sendto(serversocket,request,sizeof(request),0,(sockaddr*)&clientaddr,sizeof(clientaddr));
//waiting for the fifth command. printf("\nWaiting for the mail\n"); recvfrom(serversocket,request,sizeof(request),0,(sockaddr*)&clientaddr,&len); strcpy(mail,request);
cls(); printf("\n\n\n\t\t\tTHE DETAILS INCLUDE:\n"); printf("\n\n\t\t%s",from); printf("\n\n\t\t%s",to); printf("\n\n\t\tMAIL:%s",mail); printf("\n\n\nSEARCHING FOR THE RECIPIENT AND MESSAGE PASSED FOR SENDING.");
printf("\nPRESS ENTER TO SEND THE RESPONSE.\n"); fgets(request,2,stdin); printf("\nSending the POSITIVE COMPLETION REPLY:250\n"); strcpy(request,"250 REQUEST COMMAND COMPLETED."); sendto(serversocket,request,sizeof(request),0,(sockaddr*)&clientaddr,sizeof(clientaddr));
//waiting for the quit command. printf("\nWaiting for the next request.\n"); recvfrom(serversocket,request,sizeof(request),0,(sockaddr*)&clientaddr,&len); cls(); printf("\nThe client has send:\t%s\n",request);
printf("\nPRESS ENTER TO SEND THE RESPONSE.\n"); fgets(request,2,stdin); printf("\nSending the 221:SERVICE CLOSING.\n"); strcpy(request,"221:SERVICE CLOSING."); sendto(serversocket,request,sizeof(request),0,(sockaddr*)&clientaddr,sizeof(clientaddr));
//closing cls(); printf("\n\n\nSERVER SHUTTING DOWN.\n"); close(serversocket);}
Department Of Computer Science BM II College Of Engineering, Sasthamcotta146
Network-OS Lab Manual
Output
Department Of Computer Science BM II College Of Engineering, Sasthamcotta147
Network-OS Lab Manual
+
Department Of Computer Science BM II College Of Engineering, Sasthamcotta148
Network-OS Lab Manual
Client
Algorithm
* The different steps involved in the process are...................
1.Start the process.
2.Read the required mail contents from the user.
3.Establish an UDP connection with the server.
4.Send SMTP REQUEST to the server and wait for positive reply.
5.Send the HELO command and wait for positive reply.
6.Send the MAIL FROM: command and wait for positive reply.
7.Send the RCPT TO: command and wait for positive reply.
8.Send the DATA: command and wait for positive reply.
9.Send the mail and wait for positive reply.
10.Send QUIT: command and wait for closing reply.
11.Close the connection.
12.Stop.
Program
/* Program to demonstrate the working of smtp protocol................
* This program module act as a SMTP client which works in co_ordination with an SMTP
server.
* This program establishes an UDP connection with the server and performs the required
functions.
* This module reads the mail contents from the user and sends it to a smtp server for
transmission.
* This module is compiled as 'c++ smtpclient.cpp -o b' and execute using './b' command.
Department Of Computer Science BM II College Of Engineering, Sasthamcotta149
Network-OS Lab Manual
//inculsion#include<iostream>#include<stdio.h>#include<string.h>
#include<sys/types.h>#include<netinet/in.h>#include<netdb.h>
#define cls() printf("\033[H\033[J")
int main(){ int clientsocket; sockaddr_in serveraddr; socklen_t len; hostent *server; char from[50]; char to[50]; char mail[100]; char request[50];
clientsocket=socket(AF_INET,SOCK_DGRAM,0);
bzero((char*)&serveraddr,sizeof(serveraddr)); serveraddr.sin_family=AF_INET; serveraddr.sin_port=htons(5015); server=gethostbyname("127.0.0.1"); bcopy((char*)server->h_addr,(char*)&serveraddr.sin_addr.s_addr,sizeof(server->h_addr));
len=sizeof(serveraddr); printf("\nEnter the FROM address:\n"); fgets(from,sizeof(from),stdin);
printf("\nEnter the TO address:\n"); fgets(to,sizeof(to),stdin);
printf("\nEnter the MAIL:\n"); fgets(mail,sizeof(mail),stdin);
cls();
Department Of Computer Science BM II College Of Engineering, Sasthamcotta150
Network-OS Lab Manual
//smtp request printf("\nPRESS ENTER TO BEGIN THE FIRST PROCESS.\n"); fgets(request,2,stdin);
printf("\nSending SMTP REQUEST to the server.\n"); strcpy(request,"SMTP REQUEST."); sendto(clientsocket,request,sizeof(request),0,(sockaddr*)&serveraddr,sizeof(serveraddr));
printf("\nWaiting for the server response.\n"); recvfrom(clientsocket,request,sizeof(request),0,(sockaddr*)&serveraddr,&len); cls(); printf("\nThe server has send:\t%s\n",request);
//sending helo request printf("\nPRESS ENTER TO SEND THE FIRST COMMAND.\n"); fgets(request,2,stdin);
printf("\nSending the HELO command\n"); strcpy(request,"HELO"); sendto(clientsocket,request,sizeof(request),0,(sockaddr*)&serveraddr,sizeof(serveraddr));
printf("\nWaiting for the server response.\n"); recvfrom(clientsocket,request,sizeof(request),0,(sockaddr*)&serveraddr,&len); cls(); printf("\nThe server has send:\t%s\n",request);
//sending mail from command. printf("\nPRESS ENTER TO BEGIN THE SECOND COMMAND.\n"); fgets(request,2,stdin);
printf("\nSending the MAIL FROM request.\n"); strcpy(request,"MAIL FROM:"); strcat(request,from); sendto(clientsocket,request,sizeof(request),0,(sockaddr*)&serveraddr,sizeof(serveraddr));
printf("\nWaiting for the server response.\n"); recvfrom(clientsocket,request,sizeof(request),0,(sockaddr*)&serveraddr,&len); cls(); printf("\nThe server has send:\t%s\n",request);
//sending rcpt command. printf("\nPRESS ENTER TO BEGIN THE THIRD COMMAND.\n"); fgets(request,2,stdin);
printf("\nSending the RCPT TO request.\n");
Department Of Computer Science BM II College Of Engineering, Sasthamcotta151
Network-OS Lab Manual
strcpy(request,"RCPT TO:"); strcat(request,to); sendto(clientsocket,request,sizeof(request),0,(sockaddr*)&serveraddr,sizeof(serveraddr));
printf("\nWaiting for the server response.\n"); recvfrom(clientsocket,request,sizeof(request),0,(sockaddr*)&serveraddr,&len); cls(); printf("\nThe server has send:\t%s\n",request);
//sending data command. printf("\nPRESS ENTER TO BEGIN THE FOURTH COMMAND.\n"); fgets(request,2,stdin);
printf("\nSending the DATA request.\n"); strcpy(request,"DATA:"); sendto(clientsocket,request,sizeof(request),0,(sockaddr*)&serveraddr,sizeof(serveraddr));
printf("\nWaiting for the server response.\n"); recvfrom(clientsocket,request,sizeof(request),0,(sockaddr*)&serveraddr,&len); cls(); printf("\nThe server has send:\t%s\n",request);
//sending mail. printf("\nPRESS ENTER TO BEGIN SENDING THE MAIL.\n"); fgets(request,2,stdin);
printf("\nSending the mail.\n"); strcpy(request,mail); sendto(clientsocket,request,sizeof(request),0,(sockaddr*)&serveraddr,sizeof(serveraddr));
printf("\nWaiting for the server response.\n"); recvfrom(clientsocket,request,sizeof(request),0,(sockaddr*)&serveraddr,&len); cls(); printf("\nThe server has send:\t%s\n",request);
//sending the quit command. printf("\nPRESS ENTER TO BEGIN THE LAST COMMAND.\n"); fgets(request,2,stdin);
printf("\nSending the QUIT request.\n"); strcpy(request,"QUIT:"); sendto(clientsocket,request,sizeof(request),0,(sockaddr*)&serveraddr,sizeof(serveraddr));
printf("\nWaiting for the server response.\n"); recvfrom(clientsocket,request,sizeof(request),0,(sockaddr*)&serveraddr,&len);
Department Of Computer Science BM II College Of Engineering, Sasthamcotta152
Network-OS Lab Manual
cls(); printf("\nThe server has send:\t%s\n",request);
printf("\n\nCLIENT CLOSING DOWN.\n\n");
close(clientsocket);}
Output
Department Of Computer Science BM II College Of Engineering, Sasthamcotta153
Network-OS Lab Manual
Department Of Computer Science BM II College Of Engineering, Sasthamcotta154
Network-OS Lab Manual
REMOTE PROCEDURE CALL
Theory
When a process on machine 1 calls a procedure on machine 2, the calling process on
1 is suspended and execution of called procedure takes place on 2.Information can be
transported from the caller to callee in the parmeters and can come back in the procedure
result.No message passing is visible to the programmer. This technique is known as
RPC(Remote Procedure Call) and has become the basis for many networking applications.
Traditionally, the calling procedure is known as the client and the called procedure is known
as the server, and we will use those names here too.
The idea behind RPC is to make a remote procedure call lok as much as possible like
local one. In the simplest form, to call a remoter procedure, the client program must be bound
with a small library procedure, called the client stub, that represents the server procedure in
the server stub. These procedures hide the fact that the procedure call from the client to sever
is not local.
Program
Department Of Computer Science BM II College Of Engineering, Sasthamcotta155
Network-OS Lab Manual
/********************** finger.x **************************/
struct finger_out{
char message[1024];
};
program FINGER{
version FINGER_VERSION{
finger_out MyFinger() = 1;
} = 1;
} = 0x21230000;
/********************** client.c **************************/
#include <rpc/rpc.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "finger.h"
void err_quit(char *msg)
{
printf("%s\n", msg);
exit(1);
}
int main(int argc, char* argv[])
{
CLIENT *c1;
finger_out *outp;
Department Of Computer Science BM II College Of Engineering, Sasthamcotta156
Network-OS Lab Manual
if(argc!=2)
err_quit("usage: client <hostname>");
c1 = clnt_create(argv[1], FINGER, FINGER_VERSION, "tcp");
if( (outp=myfinger_1(NULL, c1))==NULL )
err_quit(clnt_sperror(c1, argv[1]));
printf("result: %s\n", outp->message);
exit(0);
}
/********************** server.c **************************/
#include <rpc/rpc.h>
#include <stdio.h>
#include <stdlib.h>
#include "finger.h"
finger_out* myfinger_1_svc(void *dummy, struct svc_req *rqstp)
{
static finger_out fo;
char buffer[1024];
system("finger > result.txt");
FILE *fp = fopen("result.txt", "r");
int i=0;
while( !feof(fp) ){
buffer[i++] = fgetc(fp);
}
buffer[i] = '\0';
strcpy(fo.message, buffer);
system("rm -f result.txt");
return &fo;
Department Of Computer Science BM II College Of Engineering, Sasthamcotta157
Network-OS Lab Manual
}
Output
compiling RPC:
there are 3 files initially, which we code... finger.x, client.c, server.c
compile in the following order...
do this in both the client and server systems
rpcgen -C finger.x (thats a C, not c)
gcc -c client.c -o client
gcc -c server.c -o server
gcc -c finger_clnt.c -o f_c
gcc -c finger_svc.c -o f_s
gcc -c finger_xdr.c -o f_x
In the server system, do:
gcc -o fs server f_s f_x
In the client system, do:
gcc -o fc client f_c f_x
Now run as before,
./fs <port>
./fc <IP> <port>
Department Of Computer Science BM II College Of Engineering, Sasthamcotta158
Network-OS Lab Manual
COMMON GATEWAY INTERFACE
Theory
The traditional way to handle forms and other interactive Web pages is a system
called the CGI(Common Gateway Interface).It is a standardized interface to allow web
servers to talk to backend programs and scripts that can accept input and generate html pages
in response. Usually these backends are scripts written in the Perl scripting language because
perl scripts are easier and faster to write than programs.By convention they live in a directory
called cgi-bin, which is invisible in the URL.Sometimes another scripting language, Python
is used instead of Perl.
As an example of how CGI often works, consider the case of a product from the
Truly Great Products Company that comes without a warranty registration card. Instead the
customer is told to go to www.tgpc.com to register online.On that page there is e hyperlink
that says :
Click here to register your product
This link points to a Perl script, say,www.tgpc.com/cgi-bin/reg.perl.
Department Of Computer Science BM II College Of Engineering, Sasthamcotta159
Network-OS Lab Manual
When this script is invoked with no parameters, it sends back an html page containing
the registration form.When the user fills in the form and clicks on submit, a message is sent a
back to this script contai8ning the values filled by the user.The perl script than parses the
parameters, makes an entry in the database for the new customer, and sends back an html
page providing a registration number and the telephone number for the help desk.
SAMPLE QUESTIONS
1. Implementation of dinning philosophers problem by multiprogramming using threads
2. Implementation of dinning philosophers problem using Semaphores
3. Implementation of dinning philosophers problem using Shared memory
4. Program to generate disk usage status report for a give UNIX/DOS formatted floppy
disk giving details like free space availability ets
5. Implementation of bankers algorithm
6. Implementation of interprocess communication using mailboxes
7. Implementation of interprocess communication using pipes
8. Implementation of PC to PC file transfer using serial port
9. Implementation of PC to PC file transfer using modem
10. S/W simulation of MAC protocols
Go Back N
Selective repeat
Sliding windows
11. Implementation of subset of SMTP using UDP
Department Of Computer Science BM II College Of Engineering, Sasthamcotta160
Network-OS Lab Manual
12. Implementation of subset of FTP using TCP/IP
13. Implementation of finger utility using RPC
14. Generation and processing of HTML using CGI
Department Of Computer Science BM II College Of Engineering, Sasthamcotta161