Anda di halaman 1dari 160

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

-1-

BM II College Of Engineering, Sasthamcotta

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

-2-

BM II College Of Engineering, Sasthamcotta

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

-3-

BM II College Of Engineering, Sasthamcotta

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

-4-

BM II College Of Engineering, Sasthamcotta

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

-5-

BM II College Of Engineering, Sasthamcotta

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 pseudosimultaneously) 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

-6-

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

Thread Basics
y

Thread

operations

include

thread

creation,

termination,

synchronization

(joins,blocking), scheduling, data management and process interaction.


y

A thread does not maintain a list of created threads, nor does it know the thread that created it.

y y

All threads within a process share the same address space. Threads in the same process share:
o o o o o o

Process instructions Most data open files (descriptors) signals and signal handlers current working directory User and group id

Each thread has a unique:


o o o o o o

Thread ID set of registers, stack pointer stack for local variables, return addresses signal mask priority 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

-7-

BM II College Of Engineering, Sasthamcotta

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: y detached state(joinable? Default: PTHREAD_CREATE_JOINABLE.Other

option:PTHREAD_CREATE_DETACHED) y schedulingpolicy(realtime?PTHREAD_INHERIT_SCHED,PTHREAD_EXPLICIT_ SCHED,SCHED_OTHER) y y scheduling parameter inheritsched attribute(Default:PTHREAD_EXPLICIT_SCHED,inherit from parent thread:PTHREAD_INHERIT_SCHED) y scope(Kernelthreads:PTHREAD_SCOPE_SYSTEM user threads

PTHREAD_SCOPE_PROCESS, pick one or the other not both) y y y 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

Department Of Computer Science

-8-

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

mutexes Mutual exclusion lock: Block access to variable by other threads. This enforces exclusive access by thread to a variable or set of variables.

y y

joinsMake 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:
y

Less time to create a new thread than a process, because the newly created

thread uses the current process address space.


y y

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.
y

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.

Department Of Computer Science

-9-

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

8. Stop.

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*); int main() { int error; pthread_t thread_id; pthread_attr_t thread_attribute; //variable to check error (optional) //variable to store thread id. //variable to store properties of thread. //prototype of the thread function. //main function (return type should be int in linux).

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); }

Department Of Computer Science

- 10 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

error=pthread_join(thread_id,NULL);

//function for thread calling. //error checking (optional)

if(error!=0) { printf("\nError in thread joining.\n"); exit(0); } } 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); } //function definition for the thread function.

Output

Department Of Computer Science

- 11 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

MULTIPLE THREAD
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);

Department Of Computer Science

- 12 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

//to wait for the thread to finish execution. while(end<2) { } } //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

Department Of Computer Science

- 13 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

DYNAMIC MULTITHREAD CREATION


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[]);

Department Of Computer Science

- 14 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

//variable to know the end of threads execution. int end; int main() { int i,count,j; 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

- 15 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

Output

Department Of Computer Science

- 16 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

SEMAPHORE
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.

Department Of Computer Science

- 17 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

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 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);
y

sem points to a semaphore object to initialize

Department Of Computer Science

- 18 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

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);

To wait on a semaphore, use sem_wait: int sem_wait(sem_t *sem); Example of use: sem_wait(&sem_name);
y

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);
y

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);
y

gets the current value of sem and places it in the location pointed to by valp

Example of use: int value;

Department Of Computer Science

- 19 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

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);


y

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 sem_wait (&mutex); --a = data; a = a+1; data = a; sem_post (&mutex); /* blocked */ /* blocked */ /* blocked */ /* blocked */ b = data; b = b + 1; data = b; sem_post (&mutex); Thread 2 --sem_wait (&mutex); /* blocked */ /* blocked */ /* blocked */ /* blocked */ data 0 0 0 0 1 1 1 1 2 2

[data is fine. The data race is gone.]

Department Of Computer Science

- 20 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

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. * 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 //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++)
Department Of Computer Science

'./a.out'

- 21 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

{ 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() { 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

Department Of Computer Science

- 22 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

SERIALISABILITY PROBLEM. (By using Semaphore Variable) Program


* 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) { }
Department Of Computer Science

- 23 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

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"); 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");

Department Of Computer Science

- 24 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

end++; }

Output

Department Of Computer Science

- 25 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

DINING PHILOSOPHERS PROBLEM


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

- 26 -

BM II College Of Engineering, Sasthamcotta

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

- 27 -

BM II College Of Engineering, Sasthamcotta

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

- 28 -

BM II College Of Engineering, Sasthamcotta

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");

Department Of Computer Science

- 29 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

printf("\n\n\t\tNO. OF FORKS(SPOONS):5\n\n"); printf("_____________________________________________________________________ ________________"); 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++; }

Department Of Computer Science

- 30 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

//philosopher2. void * philosopher2() { 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 3 void * 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);

Department Of Computer Science

- 31 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

sem_post(&sem23); sem_post(&sem34); 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);

Department Of Computer Science

- 32 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

sem_wait(&sem45); sem_wait(&sem15); 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

- 33 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

Department Of Computer Science

- 34 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

BANKERS ALGORITHM
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 predetermined 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:
y y y

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.

Department Of Computer Science

- 35 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

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 number of resources are abstracted. Real systems, for example, would deal with much larger quantities of each resource. Available system resources: ABCD 3112 Processes (currently allocated resources): ABCD P1 1 2 2 1 P2 1 0 3 3 P3 1 1 1 0 Processes (maximum resources): ABCD 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.

Department Of Computer Science

- 36 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

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. 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.

Department Of Computer Science

- 37 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

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

2. Assume that the request is granted 3. Is the new state safe?


o o

If so grant the request 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

Department Of Computer Science

- 38 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

Processes (currently allocated resources): ABCD P1 1 2 2 1 P2 1 0 3 3 P3 1 1 2 0

Processes (maximum resources): ABCD P1 3 3 2 2 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: ABCD Free 3 0 1 2 Processes (currently allocated resources): ABCD P1 1 2 2 1 P2 1 1 3 3 P3 1 1 1 0

Department Of Computer Science

- 39 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

Processes (maximum resources): ABCD 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 o o o

P1 is unable to acquire enough B resources P2 is unable to acquire enough B resources P3 is unable to acquire enough C resources 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.

Department Of Computer Science

- 40 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

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. * 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'

Department Of Computer Science

- 41 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

//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]; 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_allocate d_res[0][3]=1; cur_allocated_res[1][0]=1;cur_allocated_res[1][1]=0;cur_allocated_res[1][2]=3;cur_allocate d_res[1][3]=3; cur_allocated_res[2][0]=1;cur_allocated_res[2][1]=1;cur_allocated_res[2][2]=1;cur_allocate d_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_queu e[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;

Department Of Computer Science

- 42 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

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]); 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())

Department Of Computer Science

- 43 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

{ printf("\nSafe state detected\nResources allocated\n"); allocate(wait_queue[j]); j--; } else { break; } } } } delay(); i++; } } 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];

Department Of Computer Science

- 44 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

} } 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; 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");

Department Of Computer Science

- 45 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

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]); } printf("\n\t\t"); } printf("\n\n\tPRESS ENTER TO START THE PROCESS...\n"); fgets(a,2,stdin); }

Output

Department Of Computer Science

- 46 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

Department Of Computer Science

- 47 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

Department Of Computer Science

- 48 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

Department Of Computer Science

- 49 -

BM II College Of Engineering, Sasthamcotta

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

- 50 -

BM II College Of Engineering, Sasthamcotta

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 336 ./nw . Size Used Avail Use % Mounted On /dev/mapper/VolGroup00-Log Vo100 35G 3.2G 30G 10% / /dev/hda1 None 99M 12M 82M 13% /boot 498M 0 498M 0% /dev/shm

FileSystem

Department Of Computer Science

- 51 -

BM II College Of Engineering, Sasthamcotta

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

- 52 -

BM II College Of Engineering, Sasthamcotta

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

- 53 -

BM II College Of Engineering, Sasthamcotta

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

- 54 -

BM II College Of Engineering, Sasthamcotta

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

- 55 -

BM II College Of Engineering, Sasthamcotta

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

- 56 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

Output

Department Of Computer Science

- 57 -

BM II College Of Engineering, Sasthamcotta

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

- 58 -

BM II College Of Engineering, Sasthamcotta

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

- 59 -

BM II College Of Engineering, Sasthamcotta

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

- 60 -

BM II College Of Engineering, Sasthamcotta

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

- 61 -

BM II College Of Engineering, Sasthamcotta

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.

Department Of Computer Science

- 62 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

shmdt(address); //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'

Department Of Computer Science

- 63 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

//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 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) { }

Department Of Computer Science

- 64 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

printf("\nEnter your message.(type 'end' to exit)\n"); 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

- 65 -

BM II College Of Engineering, Sasthamcotta

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

- 66 -

BM II College Of Engineering, Sasthamcotta

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

- 67 -

BM II College Of Engineering, Sasthamcotta

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

- 68 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

if(pid2==0) { read(fd1[0],&n,sizeof(n)); firstfact(n); } //parent else { scanf("%d",&n); write(fd1[1],&n,sizeof(n)); write(fd2[1],&n,sizeof(n)); } } //child2 else { 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

- 69 -

BM II College Of Engineering, Sasthamcotta

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

- 70 -

BM II College Of Engineering, Sasthamcotta

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

- 71 -

BM II College Of Engineering, Sasthamcotta

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

- 72 -

BM II College Of Engineering, Sasthamcotta

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

- 73 -

BM II College Of Engineering, Sasthamcotta

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

- 74 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

#include<string.h> #include<sys/types.h> #include<unistd.h> #define size 4096

//CONVERTING STARTING ADDRESS OF SHARED MEMORY TO STRING void 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 MEMORY void 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

- 75 -

BM II College Of Engineering, Sasthamcotta

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 MEMORY sh_mem_id=shmget(IPC_PRIVATE,size,IPC_CREAT|IPC_EXCL|S_IRUSR|S_IWU SR|S_IROTH|S_IWOTH); shared_mem=(int *)shmat(sh_mem_id,0,0);//ATTACH MEMORY //CONVERT ADDRESS TO STRING itoa(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 MEMORY shared_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 ADDRESS address=address+(r1*c1); //FOR MATRIX B

Department Of Computer Science

- 76 -

BM II College Of Engineering, Sasthamcotta

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 C system("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 CHILD child=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 MEMORY printf("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

- 77 -

BM II College Of Engineering, Sasthamcotta

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 MEMORY void 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

- 78 -

BM II College Of Engineering, Sasthamcotta

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 MEMORY r1=shared_mem[0]; c1=shared_mem[1]; //READ MATRIX A read_from_shm(A,shared_mem,add,r1,c1); add=add+(r1*c1); //SKIP MATRIX B r2=shared_mem[2]; c2=shared_mem[3]; add=add+(r2*c2); //READ MATRIX C r3=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

- 79 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

//READ MATRIX D r3=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 MEMORY shmctl(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

- 80 -

BM II College Of Engineering, Sasthamcotta

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

- 81 -

BM II College Of Engineering, Sasthamcotta

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

- 82 -

BM II College Of Engineering, Sasthamcotta

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 sender g++ <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

- 83 -

BM II College Of Engineering, Sasthamcotta

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 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>

For threaded programs, compile with g++ <program.cpp> -lpthread For dining philosopher using ncurses lib, g++ dining.cpp -lpthread -lcurses if that doesn't work g++ -I/usr/include/ncurses dining.cpp -lpthread

Department Of Computer Science

- 84 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

NETWORKING

Department Of Computer Science

- 85 -

BM II College Of Engineering, Sasthamcotta

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

Department Of Computer Science

- 86 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

-- provides two-way, sequenced, reliable, and unduplicated flow of data with no record boundaries. A stream operates much like a telephone conversation. The socket 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.

Department Of Computer Science

- 87 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

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.
y

For UNIX domain sockets with paths containing 14, or fewer characters, you

can:
y #include <sys/socket.h> y ... y bind (sd, (struct sockaddr *) &addr, length); y

If the path of a UNIX domain socket requires more characters, use:

y #include <sys/un.h> y ... y bind (sd, (struct sockaddr_un *) &addr, length); y

For Internet domain sockets, use

y #include <netinet/in.h> y ... y 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);

Department Of Computer Science

- 88 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

while an Internet domain call would be: struct sockaddr_in; ... 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.

Department Of Computer Science

- 89 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

A SOCK_STREAM socket is discarded by calling close(). 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

- 90 -

BM II College Of Engineering, Sasthamcotta

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));
Department Of Computer Science BM II College Of Engineering, Sasthamcotta

- 91 -

Network-OS Lab Manual

len=sizeof(clientaddr); //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.")); close(clientsocket); close(serversocket); }

RECEIVED.",sizeof("YOUR

MESSAGE

Output

Department Of Computer Science

- 92 -

BM II College Of Engineering, Sasthamcotta

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];
Department Of Computer Science

- 93 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

//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 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); }

AM

Output

Department Of Computer Science

- 94 -

BM II College Of Engineering, Sasthamcotta

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;

Department Of Computer Science

- 95 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

//variable to store the network addresses. sockaddr_in serveraddr,clientaddr; //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); }

Department Of Computer Science

- 96 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

Output

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.

Department Of Computer Science

- 97 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

//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. 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); }

Department Of Computer Science

- 98 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

Output

Department Of Computer Science

- 99 -

BM II College Of Engineering, Sasthamcotta

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 sevenlayer 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 pointto-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.

Department Of Computer Science

- 100 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

SLIDING WINDOW PROTOCOL


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

Department Of Computer Science

- 101 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

acknowledgement before sending the next one. The starting machine fetches the first packet 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 senders window size starts out at 0 and grows to some predefined maximum. The receivers 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

- 102 -

BM II College Of Engineering, Sasthamcotta

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

- 103 -

BM II College Of Engineering, Sasthamcotta

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

Department Of Computer Science

- 104 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

int main() { 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*)&clien taddr,&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");

Department Of Computer Science

- 105 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

sendto(serversocket,(char*)&totalpackets,sizeof(totalpackets),0,(sockaddr*)&clientad dr,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*)&clientadd r,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,(socka ddr*)&clientaddr,&len); cls();

Department Of Computer Science

- 106 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

//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]); 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

- 107 -

BM II College Of Engineering, Sasthamcotta

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

- 108 -

BM II College Of Engineering, Sasthamcotta

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

- 109 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

//structure definition for accepting the packets. struct frame { int packet[40]; }; //structure definition for constructing the acknowledgement frame struct 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

- 110 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

sendto(clientsocket,(char*)&windowsize,sizeof(windowsize),0,(sockaddr*)&serverad dr,sizeof(serveraddr)); cls(); //collecting details from server. printf("\nWaiting for the server response.\n"); recvfrom(clientsocket,(char*)&totalpackets,sizeof(totalpackets),0,(sockaddr*)&serve raddr,&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*)&servera ddr,&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.

Department Of Computer Science

- 111 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

j=0; l=buffer; k=0; while(j<windowsize && l<totalpackets) { 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

- 112 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

Department Of Computer Science

- 113 -

BM II College Of Engineering, Sasthamcotta

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

- 114 -

BM II College Of Engineering, Sasthamcotta

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

- 115 -

BM II College Of Engineering, Sasthamcotta

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

- 116 -

BM II College Of Engineering, Sasthamcotta

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,size of(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; while( l<totalpackets) { //starting the process of sending //initialising the transmit buffer.

Department Of Computer Science

- 117 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

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. 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++;

Department Of Computer Science

- 118 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

} m++; n++; } 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

- 119 -

BM II College Of Engineering, Sasthamcotta

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

- 120 -

BM II College Of Engineering, Sasthamcotta

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

- 121 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

}; //structure definition for constructing the acknowledgement frame struct 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*)&serverad dr,sizeof(serveraddr));

Department Of Computer Science

- 122 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

cls(); //collecting details from server. printf("\nWaiting for the server response.\n"); recvfrom(clientsocket,(char*)&totalpackets,sizeof(totalpackets),0,(sockaddr*)&serve raddr,&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*)&servera ddr,&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);

Department Of Computer Science

- 123 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

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; 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); }

Department Of Computer Science

- 124 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

Output

Department Of Computer Science

- 125 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

SLIDING WINDOW PROTOCOL


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

Department Of Computer Science

- 126 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

waits for the acknowledgement. * If a negative (-1) acknowledgement is received the frame is transmitted again, else the next 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));

Department Of Computer Science

- 127 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

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,size of(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) {

Department Of Computer Science

- 128 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

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) { 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); }

Department Of Computer Science

- 129 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

Output

Department Of Computer Science

- 130 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

Client Algorithm
* 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.

Department Of Computer Science

- 131 -

BM II College Of Engineering, Sasthamcotta

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 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);

Department Of Computer Science

- 132 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

//sending the window size. printf("\n\nSending the window size.\n"); sendto(clientsocket,(char*)&windowsize,sizeof(windowsize),0,(sockaddr*)&serveraddr,size of(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(s erveraddr));

recvfrom(clientsocket,(char*)&totalframes,sizeof(totalframes),0,(sockaddr*)&serveraddr,&l en); printf("\nThe total frames/windows are:\t%d\n",totalframes); sendto(clientsocket,"RECEIVED.",sizeof("RECEIVED."),0,(sockaddr*)&serveraddr,sizeof(s erveraddr)); //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);

Department Of Computer Science

- 133 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

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 { framesreceived++; } //sending acknowledgement to the server. sendto(clientsocket,(char*)&acknowledgement,sizeof(int),0,(sockaddr*)&serveraddr,sizeof(s erveraddr)); cls(); } printf("\nAll frames received successfully.\n\nClosing connection with the server.\n"); close(clientsocket); }

Output

Department Of Computer Science

- 134 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

Department Of Computer Science

- 135 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

FILE TRANSFER PROTOCOL


Theory

The FTP protocol is used to access files by FTP, the internets 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.

Department Of Computer Science

- 136 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

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 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);

Department Of Computer Science

- 137 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

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); 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); }

Department Of Computer Science

- 138 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

Output

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.

Department Of Computer Science

- 139 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

* This module is designed with a view to represent the ftp process with simplicity, so it only sends and receives data. * 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);

Department Of Computer Science

- 140 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

fclose(ptr); close(clientsocket); }

Output

Department Of Computer Science

- 141 -

BM II College Of Engineering, Sasthamcotta

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

- 142 -

BM II College Of Engineering, Sasthamcotta

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.

Department Of Computer Science

- 143 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

* NOTE: This module just immitate as a SMTP server. * 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);

Department Of Computer Science

- 144 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

printf("The request received is:\t%s",request); printf("\nPRESS ENTER TO SEND THE RESPONSE.\n"); fgets(request,2,stdin); 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");

Department Of Computer Science

- 145 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

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"); 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));

Department Of Computer Science

- 146 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

//closing cls(); printf("\n\n\nSERVER SHUTTING DOWN.\n"); close(serversocket); }

Output

Department Of Computer Science

- 147 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

Department Of Computer Science

- 148 -

BM II College Of Engineering, Sasthamcotta

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

- 149 -

BM II College Of Engineering, Sasthamcotta

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(); //smtp request printf("\nPRESS ENTER TO BEGIN THE FIRST PROCESS.\n");

Department Of Computer Science

- 150 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

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"); strcpy(request,"RCPT TO:"); strcat(request,to);

Department Of Computer Science

- 151 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

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); cls(); printf("\nThe server has send:\t%s\n",request);

Department Of Computer Science

- 152 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

printf("\n\nCLIENT CLOSING DOWN.\n\n"); close(clientsocket); }

Output

Department Of Computer Science

- 153 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

Department Of Computer Science

- 154 -

BM II College Of Engineering, Sasthamcotta

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
/********************** finger.x **************************/ struct finger_out{ char message[1024]; };

program FINGER{ version FINGER_VERSION{ finger_out MyFinger() = 1;

Department Of Computer Science

- 155 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

} = 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;

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); }

Department Of Computer Science

- 156 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

/********************** 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

- 157 -

BM II College Of Engineering, Sasthamcotta

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

- 158 -

BM II College Of Engineering, Sasthamcotta

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.

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

Department Of Computer Science

- 159 -

BM II College Of Engineering, Sasthamcotta

Network-OS Lab Manual

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 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

- 160 -

BM II College Of Engineering, Sasthamcotta

Anda mungkin juga menyukai