CNOS - Lab - Manual - 2019-20 DT 17-6-19
CNOS - Lab - Manual - 2019-20 DT 17-6-19
CNOS - Lab - Manual - 2019-20 DT 17-6-19
Department of
Information Technology
CN/OS Lab
(Code: PC 531 IT)
Department of
Information Technology
CN/OS Lab
(Code: PC 531 IT)
Department of
Information Technology
Manual and Observation Book
CN/OS Lab
(Code: PC 531 IT)
CLASS : SECTION
ROLL N O.
CN/OS Lab
COURSE OBJECTIVE:
1. To understand the usage of various Linux commands
2. To implement client server programs using TCP, UDP and Raw sockets
3. To simulate and compare perforamance of various protocols
4. To gain experience in shell programming
5. To implement various page replacement, CPU scheduling algorithms
6. To understand and implement semaphores and Dead lock avoidance
CN Lab
1. Basics of UNIX commands
2. Programs using TCP Sockets (like date and time server & client, echo server & client
etc.)
3. Programs using UDP Sockets (like simple DNS)
4. Programs using Raw sockets(like packet capturing and filtering)
5. Programs using RPC
6. Simulation of sliding window protocols
7. Using Network simulator perform the following experiments.
a. Performance comparison of MAC protocols
b. Performance comparison of routing protocols
c. Study of TCP/UDP performance
OS lab
1. Shell Programming
2. Implement the following CPU scheduling algorithm
a. Round Robin
b. SJF
c. FCFS
d. Priority
3. Implement various file allocation strategies
4. Implement semaphores
5. Implement Bankers algorithm for Dead Lock Avoidance
6. Implement various page replacement algorithms.
M.V.S.R.ENGINEERINGCOLLEGE
CN/OS Lab
Course Outcomes:
End of the course student should able to
• Learn LINUX- platform and shell script
• Implement programs based on clident server programs using TCP,UDP and Raw sockets
• Compare and check the performance of various protocols using simulator.
• Solve synchronization problems occurs in operating systems by using semaphores
• Implement programs on Process Scheduling Algorithms and page replacement
Algorithms
• Implement programs on semaphores and Dead Lock avoidance using Bankers algorithm
M.V.S.R.ENGINEERINGCOLLEGE
Department of
Information Technology
CN/ OS Laboratory
NAME
CLASS : SECTION
ROLL NO. ________________________________________________________________
INDEX
Date of Date of
S.No. Name of the Experiment Expt. Grade/Marks Signature Remarks
Conducted Submission
7
LIST OF EXPERIMENTS
CN Lab Programs
1. Programs using TCP Sockets (like date and time server & client, echo server & client,
etc.)
2. Programs using UDP Sockets (like simple DNS)
3. Programs using Raw sockets (like packet capturing and filtering)
4. Programs using RPC
5. Simulation of sliding window protocols
6. Experiments using simulators (like OPNET)
7. Performance comparison of MAC protocols
8. Performance comparison of Routing protocols
9. Study of TCP/UDP performance
OS Lab programs
8
LAB SCHEDULE:
CN/OS LAB
Class: 3/4 Section: A & B Batch:A & B
Week Experiments Date Date
Planned Conducted
Week 1 Basics of UNIX commands
Write a shell program to find whether the given
number is palindrome or not.
Write a shell program to find whether the given
number is armstrong or not
9
INTRODUCTION TO COMPUTER NETWORK PROGRAMMING LABORATORY
NETWORKING BASICS
➢ Iterative servers: This server knows ahead of time about how long it takes to handle
eachrequest & server process handles each request itself.
Iterative Server
➢ Concurrent servers: The amount of work required to handle a request is unknown,
so the server starts another process to handle each request.
Concurrent Server
10
Client: A Client is an application that runs on a personal computer or workstation and relies
on a server to perform some operations.
Network Address: Network addresses give computers unique identities they can use to
communicate with each other. Specifically, IP addresses and MAC addresses are used on
most home and business networks.
Protocols: A Protocol is a convention or standard rules that enables and controls the
connection, communication and data transfer between two computing endpoints.
Port An interface on a computer to which you can connect a device. It is a "logical
connection place" and specifically, using the Internet's protocol, TCP/IP.
A port is a 16-bit number, used by the host-to-host protocol to identify to which higher-level
protocol or application program (process) it must deliver incoming messages.
PORTS RANGE
Well-known ports 1-1023
Ephemeral ports 1024-5000
User-defined ports 5001-65535
Table 1: Ports and Ranges
Connection: It defines the communication link between two processes.
Association: Association is used for 5 tuple that completely specifies the two processes that
make up a connection.
{ Protocol, local-address, local-process, foreign-address, foreign- process}
The local address and foreign address specify the network ID & Host-ID of the local host and
the foreign host in whatever format is specified by protocol suite.
The local process and foreign process are used to identify the specific processes on each
system that are involved in a connection.
We also define Half association as either
{ protocol, local-address, local process} or { protocol, local-address, local process}
which specify each half of a connection. This half association is called a Socket or transport
address.
11
Connection-oriented and Connectionless Flow
OSI Model
A common way to describe the layers in a network is to use the International Organization for
Standardization (ISO) open systems interconnection (OSI) model for computer
communications. This is a seven-layer model, which we show in Figure below along with the
approximate mapping to the Internet protocol suite.
We consider the bottom two layers of the OSI model as the device driver and networking
hardware that are supplied with the system. The network layer is handled by the IPv4 and
IPv6 protocols. The transport layers that we can choose from are TCP and UDP
The upper three layers of the OSI model are combined into a single layer called the
application. This is the Web client (browser) or whatever application we are using. With the
Internet protocols, there is rarely any distinction between the upper three layers of the OSI
model.
12
The sockets programming interfaces are interfaces from the upper three layers (the
"application") into the transport layer. The sockets provide the interface from the upper three
layers of the OSI model into the transport layer. There are two reasons for this design:
The upper three layers handle all the details of the application and know little about
the communication details. The lower four layers know little about the application,
but handle all the communication details: sending data, waiting for acknowledgments,
and so on.
The second reason is that the upper three layers often form what is called a user
process while the lower four layers are normally provided as part of the operating
system (OS) kernel.
CLIENT-SERVER MODEL
Network applications can be divided into two processes: a Client and a Server, with a
communication link joining the two processes.
Normally, from Client-side it is one-one connection. From the Server Side, it is many-one
connection.
The standard model for network applications is the Client-Server model. A Server is a
process that is waiting to be contacted by a Client process so that server can do something for
the client.
Typical BSD Sockets applications consist of two separate application level processes; one
process (the client) requests a connection and the other process (the server) accepts it.
13
Fig 2.6: Socket functions for elementary TCP client/server in Connection-oriented
Scenario
The server process creates a socket, binds an address to it, and sets up a mechanism (called a
listen queue) for receiving connection requests. The client process creates a socket and
requests a connection to the server process. Once the server process accepts a client process's
request and establishes a connection, full-duplex (two-way) communication can occur
between the two sockets.
14
UDP Server
socket()
UDP Client
socket()
bind()
bind()
recvfrom()
sendto() recvfrom()
Fig 2.7: Diagram showing the sequence of steps to be followed by the Connectionless
Iterative server and client
The server process creates a socket, binds an address to it, and waits for receiving request
messages from client. The client process creates a socket and binds an address to it,the server
process accepts a client process's request message and sends the reply message, full-duplex
(two-way) communication can occur between the two sockets.
Byte-Ordering Functions: Consider a 16-bit integer that is made up of 2 bytes. There are
two ways to store the two bytes in memory: with the low-order byte at the starting address,
known as little-endian byte order, or with the high-order byte at the starting address, known
as big-endian byte order. Little-endian byte order and big-endian byte order for a 16-bit
integer.
In this figure, we show increasing memory addresses going from right to left in the top, and
from left to right in the bottom. We also show the most significant bit (MSB) as the leftmost
bit of the 16-bit value and the least significant bit (LSB) as the rightmost bit. The terms
15
"little-endian" and "big-endian" indicate which end of the multibyte value, the little end or the
big end, is stored at the starting address of the value.
We refer to the byte ordering used by a given system as the host byte order. We must deal
with these byte ordering differences as network programmers because networking protocols
must specify a network byte order. Our concern is therefore converting between host byte
order and network byte order. We use the following four functions to convert between these
two byte orders.
#include <netinet/in.h>
#include <sys/types.h>
unsigned long htonl(unsigned long hostlong) ;
unsigned short htons(unsigned short hostshort) ;
unsigned long ntohl(unsigned long netlong) ;
unsigned short ntohs(unsigned short netshort) ;
The operating system includes the Berkeley Software Distribution (BSD) interprocess
communication (IPC) facility known as sockets. Sockets are communication channels that
enable unrelated processes to exchange data locally and across networks. A single socket is
one end point of a two-way communication channel.
16
Enable communication between unrelated processes residing locally on a single host
computer and residing remotely on multiple host machines.
Socket Facilities: Socket subroutines and network library subroutines provide the building
blocks for IPC. An application program must perform the following basic functions to
conduct IPC through the socket layer:
Create and name sockets.
Accept and make socket connections.
Send and receive data.
Shut down socket operations.
Socket Interface: The Socket interface provides a standard, well-documented approach to
access kernel network resources.
Socket Header Files to be Included: Socket header files contain data definitions, structures,
constants, macros, and options used by socket subroutines. An application program must
include the appropriate header file to make use of structures or other information a particular
socket subroutine requires. Commonly used socket header files are:
/usr/include/netinet/in.h Defines Internet constants and structures.
/usr/include/netdb.h Contains data definitions for socket subroutines.
/usr/include/sys/socket.h Contains data definitions and socket structures.
/usr/include/sys/types.h Contains data type definitions.
/usr/include/arpa.h Contains definitions for internet operations.
/usr/include/sys/errno.h Defines the errnovalues that are returned by drivers and
other kernel-level code.
Internet address translation subroutines require the inclusion of the inet.hfile. The inet.hfile
is located in the /usr/include/arpadirectory.
Socket Addresses: Sockets can be named with an address so that processes can connect to
them. Most socket functions require a pointer to a socket address structure as an argument.
Each supported protocol suite defines its own socket address structure. The names of these
structures begin with sockaddr_ and end with a unique suffix for each protocol suite.
Generic socket address structure: Many of the Networking system calls require a pointer to
a socket address structure as an argument.
Definition of this structure is in
#include<sys/socket.h>
structsockaddr {
unsigned short sa_family; /* address family : AF_xxx Value */
charsa_data[14]; /* up to1714 bytes of protocol- specific address */
};
Internet Socket address structure: The protocol specific structure sockaddr_in is identical
in size to generic structure which is 16 bytes.
#include <netinet/in.h>
structsockaddr_in {
shortsin_family; /* AF_INET
unsigned short sin_port; /* 16-bit port number */
/* Network-byte ordered */
structin_addrsin_addr; /* 32-bit netid/hostid*/
/* Network-byte ordered */
charsin_zero[8]; /* unused*/
};
structin_addr {
unsigned long s_addr; /* 32-bit netid/hostid */
/* network byte ordered*/ };
sin_zerois unused member, but we always set it to 0 when filling in one of these structures.
Socket address structures are used only on a given host: the structure itself is now
communicated between different hosts, although certain fields (eg: IP Address & ports) are
used for communication. *The protocol-specific structure sockaddr_inis identical in size to
generic structure sockaddr which is 16 bytes
18
FEATURES OF LINUX OPERTING SYSTEM:
19
Portable - Portability means softwares can works on different types of hardwares in
same way.Linux kernel and application programs supports their installation on any
kind of hardware platform.
Open Source - Linux source code is freely available and it is community based
development project. Multiple teams works in collaboration to enhance the
capability of Linux operating system and it is continuously evolving.
Multi-User - Linux is a multiuser system means multiple users can access system
resources like memory/ ram/ application programs at same time.
Multiprogramming - Linux is a multiprogramming system means multiple
applications can run at same time.
Hierarchical File System - Linux provides a standard file structure in which system
files/ user files are arranged.
Shell - Linux provides a special interpreter program which can be used to execute
commands of the operating system. It can be used to do various types of operations,
call application programs etc.
Security - Linux provides user security using authentication features like password
protection/ controlled access to specific files/ encryption of data.
Architecture
20
Why Use Shells?
Well, most likely because the are a simple way to string together a bunch of UNIX
commands for execution at any time without the need for prior compilation. Also because its
generally fast to get a script going. Not forgetting the ease with which other scripters can read
the code and understand what is happening. Lastly, they are generally completely portable
across the whole UNIX world, as long as they have been written to a common standard.
The Shell History:
The basic shells come in three main language forms. These are (in order of creation) sh, csh
and ksh. Be aware that there are several dialects of these script languages which tend to make
them all slightly platform specific. Where these differences are known to cause difficulties I
have made special notes within the text to highlight this fact. The different dialects are due, in
the main, to the different UNIX flavours in use on some platforms. All script languages
though have at their heart a common core which if used correctly will guarantee portability.
Bourne Shell:
Historically the sh language was the first to be created and goes under the name of The
Bourne Shell. It has a very compact syntax which
Basic Unix commands
Command CAT
Syntax cat [argument] [specific file]
Description “cat" is short for concatenate. This command is used to create,
view and concatenate files.
Examples cat /etc/passwd
This command displays the "/etc/passwd" file on your screen.
cat /etc/profile
This command displays the "/etc/profile" file on your screen.
Notice that some of the contents of this file may scroll off of your
screen.
cat file1 file2 file3 > file4
This command combines the contents of the first three files into
the fourth file.
Command pwd
Syntax pwd
Description "pwd" stands for parent working directory. It displays your
current position in the UNIX filesystem.
Examples pwd
There are no options (or arguments) with the "pwd" command. It is
simply used to report your current working directory.
Command Ls
Syntax names]
Description "ls" stands for list. It is used to list information about files and
directories.
Examples ls
This is the basic "ls" command, with no options. It provides a very
basic listing of the files in your current working directory.
Filenames beginning with a decimal are considered hidden files,
and they are not shown.
ls -a
The -a option tells the ls command to report information about all
files, including hidden files.
21
ls -l
The -l option tells the "ls" command to provide a long listing of
information about the files and directories it reports. The long
listing will provide important information about file permissions,
user and group ownership, file size, and creation date.
ls -al
This command provides a long listing of information about all
files in the current directory. It combines the functionality of the -a
and -l options. This is probably the most used version of the ls
command.
ls -al /usr
This command lists long information about all files in the "/usr"
directory.
ls -alR /usr | more
This command lists long information about all files in the "/usr"
directory, and all sub-directories of /usr. The -R option tells the ls
command to provide a recursive listing of all files and sub-
directories.
ls -ld /usr
Rather than list the files contained in the /usr directory, this
command lists information about the /usr directory itself (without
generating a listing of the contents of /usr). This is very useful
when you want to check the permissions of the directory, and not
the files the directory contains.
Command Mv
Syntax mv [ptions] sources target
Options -b backup files that are about to be overwritten or removed
-i interactive mode; if dest exists, you'll be asked whether to
overwrite the file
Description The "mv" command is used to move and rename files.
Examples mv Chapter1 Chapter1.bad
This command renames the file "Chapter1" to the new name
"Chapter1.bad".
mv Chapter1 garbage
This command renames the file "Chapter1" to the new name
"garbage". (Notice that if "garbage" is a directory, "Chapter1"
would be moved into that directory).
mv Chapter1 /tmp
This command moves the file "Chapter1" into the directory named
"/tmp".
mv tmp tmp.old
Assuming in this case that tmp is a directory, this example
renames the directory tmp to the new name tmp.old.
Command Rm
Syntax iles
Options -d, --directory
unlink FILE, even if it is a non-empty directory (super-
user only)
-f, --force
22
ignore nonexistent files, never prompt
-i, --interactive
prompt before any removal
-r, -R, --recursive
remove the contents of directories recursively
-v, --verbose
explain what is being done
Description The "rm" command is used to remove files and directories.
(Warning - be very careful when removing files and directories!)
Examples rm Chapter1.bad
This command deletes the file named "Chapter1.bad" (assuming
you have permission to delete this file).
rm Chapter1 Chapter2 Chapter3
This command deletes the files named "Chapter1", "Chapter2",
and "Chapter3".
rm -i Chapter1 Chapter2 Chapter3
This command prompts you before deleting any of the three files
specified. The -i option stands for inquire. You must answer y (for
yes) for each file you really want to delete. This can be a safer way
to delete files.
rm *.html
This command deletes all files in the current directory whose
filename ends with the characters ".html".
rm index*
This command deletes all files in the current directory whose
filename begins with the characters "index".
rm -r new-novel
This command deletes the directory named "new-novel". This
directory, and all of its' contents, are erased from the disk,
including any sub-directories and files.
Command Cp
Syntax ile1 file2
iles directory
Options -b backup files that are about to be overwritten or removed
-i interactive mode; if dest exists, you'll be asked whether to
overwrite the file
-p preserves the original file's ownership, group, permissions,
and timestamp
Description The "cp" command is used to copy files and directories.
Note that when using the cp command, you must always specify
both the source and destination of the file(s) to be copied.
Examples cp .profile .profile.bak
This command copies your ".profile" to a file named
".profile.bak".
cp /usr/fred/Chapter1 .
This command copies the file named "Chapter1" in the "/usr/fred"
directory to the current directory. This example assumes that you
have write permission in the current directory.
cp /usr/fred/Chapter1 /usr/mary
23
This command copies the "Chapter1" file in "/usr/fred" to the
directory named "/usr/mary". This example assumes that you have
write permission in the "/usr/mary" directory.
Command Grep
Syntax ] regular expression [files]
Options -i case-insensitive search
-n show the line# along with the matched line
-v invert match, e.g. find all lines that do NOT match
-w match entire words, rather than substrings
Description Think of the "grep" command as a "search" command (most
people wish it was named "search"). It is used to search for text
strings within one or more files.
Examples grep 'fred' /etc/passwd
This command searches for all occurrences of the text string 'fred'
within the "/etc/passwd" file. It will find and print (on the screen)
all of the lines in this file that contain the text string 'fred',
including lines that contain usernames like "fred" - and also
"alfred".
grep '^fred' /etc/passwd
This command searches for all occurrences of the text string 'fred'
within the "/etc/passwd" file, but also requires that the "f" in the
name "fred" be in the first column of each record (that's what the
caret character tells grep). Using this more-advanced search, a user
named "alfred" would not be matched, because the letter "a" will
be in the first column.
grep 'joe' *
This command searches for all occurrences of the text string 'joe'
within all files of the current directory.
Command Mkdir
Syntax mkdir [options] directory name
Description The "mkdir" command is used to create new directories (sub-
directories).
Examples mkdir tmp
This command creates a new directory named "tmp" in your
current directory. (This example assumes that you have the proper
permissions to create a new sub-directory in your current working
directory.)
mkdir memos letters e-mail
This command creates three new sub-directories (memos, letters,
and e-mail) in the current directory.
mkdir /usr/fred/tmp
This command creates a new directory named "tmp" in the
directory "/usr/fred". "tmp" is now a sub-directory of "/usr/fred".
(This example assumes that you have the proper permissions to
create a new directory in /usr/fred.)
mkdir -p /home/joe/customer/acme
This command creates a new directory named
/home/joe/customer/acme, and creates any intermediate directories
that are needed. If only /home/joe existed to begin with, then the
24
directory "customer" is created, and the directory "acme" is created
inside of customer.
Command Rmdir
Syntax rmdir [options] directories
Description The "rm" command is used to remove files and directories.
(Warning - be very careful when removing files and directories!)
Examples rm Chapter1.bad
This command deletes the file named "Chapter1.bad" (assuming
you have permission to delete this file).
rm Chapter1 Chapter2 Chapter3
This command deletes the files named "Chapter1", "Chapter2",
and "Chapter3".
rm -i Chapter1 Chapter2 Chapter3
This command prompts you before deleting any of the three files
specified. The -i option stands for inquire. You must answer y (for
yes) for each file you really want to delete. This can be a safer way
to delete files.
rm *.html
This command deletes all files in the current directory whose
filename ends with the characters ".html".
rm index*
This command deletes all files in the current directory whose
filename begins with the characters "index".
rm -r new-novel
This command deletes the directory named "new-novel". This
directory, and all of its' contents, are erased from the disk,
including any sub-directories and files.
Command cd, chdir
Syntax directory you want to move to]
Description "cd" stands for change directory. It is the primary command for
moving around the filesystem.
Examples cd /usr
This command moves you to the "/usr" directory. "/usr" becomes
your current working directory.
cd /usr/fred
Moves you to the "/usr/fred" directory.
cd /u*/f*
Moves you to the "/usr/fred" directory - if this is the only directory
matching this wildcard pattern.
cd
Issuing the "cd" command without any arguments moves you to
your home directory.
cd -
Using the Korn shell, this command moves you back to your
previous working directory. This is very useful when you're in the
middle of a project, and keep moving back-and-forth between two
directories.
Command Kill
Syntax Ds
25
Description kill ends
one or more process IDs. In order to do this you must
own the process or be designated a privileged user. To find the
process ID of a certain job use ps.
Examples
Command Ps
Syntax
Description The "ps" command (process statistics) lets you check the status
of processes that are running on your Unix system.
Examples ps
The ps command by itself shows minimal information about the
processes you are running. Without any arguments, this command
will not show information about
otherprocessesrunningonthesystem.
ps -f
The -f argument tells ps to supply full information about the
processes it displays. In this example, ps displays full information
about the processes you are running.
ps -e
The -e argument tells the ps command to show every process
running on the system.
ps -ef
The -e and -f arguments are normally combined like this to show
full information about every process running on the system. This is
probably the most often-used form of the ps command.
ps -ef | more
Because the output normally scrolls off the screen, the output of
the ps -ef command is often piped into the more command. The
more command lets you view one screenful of information at a
time.
ps -fu fred
This command shows full information about the processes
currently being run by the user named fred (the -u option lets you
specify a username).
Process
A process is a program in execution. The execution of a process must progress in a sequential
fashion. Definition of process is following.
A process is defined as an entity which represents the basic unit of work to be
implemented in the system.
Components of process are following.
S.N. Component & Description
1 Object Program : Code to be executed.
2 Data: Data to be used for executing the program.
26
3 Resources: While executing the program, it may require some resources.
4 Status: Verifies the status of the process execution. A process can run to completion
only when all requested resources have been allocated to the process. Two or more processes
could be executing the same program, each using their own data and resources.
Program
A program by itself is not a process. It is a static entity made up of program statement while
process is a dynamic entity. Program contains the instructions to be executed by processor.
A program takes a space at single place in main memory and continues to stay there. A
program does not perform any action by itself.
Process States
As a process executes, it changes state. The state of a process is defined as the current activity
of the process.
Process can have one of the following five states at a time.
S.N. State & Description
1 New : The process is being created.
2 Ready: The process is waiting to be assigned to a processor. Ready processes are
waiting to have the processor allocated to them by the operating system so that they can run.
3 Running: Process instructions are being executed (i.e. The process that is currently
being executed).
4 Waiting: The process is waiting for some event to occur (such as the completion of an
I/O operation).
5 Terminated: The process has finished execution.
Process IDs
Process IDs are the process identifiers that are non negative numbers associated with a
process. These numbers are unique across the processes running in the system.
This uniqueness of the process ID sometimes is used by the process to create some unique
filenames. When a process is terminated from system, its process ID is made available for
reuse.
But there is a specific delay that is accounted before making the process ID available for
reuse. This is because the process ID that was associated with the previous process that is
now terminated may well be into use in form of a file name etc. So a delay is added before
reusing the same process ID.
27
Process ID 1 is for the init process. This is the first process that is started once a system
boots up.
The program file for the init process can be found either in /etc/init or in /sbin/init. The init
process is a user level process but runs with root privileges and is responsible for bringing the
system up to a state once the kernel has bootstrapped. The startup files read by the init
process to achieve a certain state are
• /etc/rc*.d
• /etc/init.d
• /etc/inittab
Process ID 0 is of the scheduler of the system. It is a kernel level process responsible for all
the process scheduling that takes place inside the system.
2. File descriptors
The operating system assigns internally to each opened file a descriptor or an identifier
(usually this is a positive integer). When opening or creating a new file the system returns a
file descriptor to the process that executed the call. Each application has its own file
descriptors. By convention, the first three file descriptors are opened at the beginning of each
process. The 0 file descriptor identifies the standard input, 1 identifies the standard output and
2 the standard output for errors. The rest of the descriptors are used by the processes when
opening an ordinary, pipe or special file, or directories. There are five system calls that
generate file descriptors: create, open, fcntl, dup and pipe.
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *path,
int flags,... /* mode_t mod */);
This function returns the file descriptor or in case of an error -1. The number of arguments
that this function can have is two or three. The third argument is used only when creating a
new file. When we want to open an existing file only two arguments are used. The function
returns the smallest available file descriptor. This can be used in the following system
calls: read, write, lseek and close. The effective UID or the effective GID of the process that
executes the call has to have read/write rights, based on the value of the argument flags. The
28
file pointer is places on the first byte in the file. The argument flags is formed by a bitwise
OR operation made on the constants defined in the fcntl.h header.
O_RDONLY
Opens the file for reading.
O_WRONLY
Opens the file for writing.
O_RDWR
The file is opened for reading and writing.
O_APPEND
It writes successively to the end of the file.
O_CREAT
The file is created in case it didn’t already exist.
O_EXCL
If the file exists and O_CREAT is positioned, calling open will fail.
O_NONBLOCK
In the case of pipes and special files, this causes the open system call and any other
future I/O operations to never block.
O_TRUNC
If the file exists all of its content will be deleted.
O_SYNC
It forces to write on the disk with function write. Though it slows down all the system,
it can be useful in critical situations.
The third argument, mod, is a bitwise OR made between a combinations of two from the
following list:
S_IRUSR, S_IWUSR, S_IXUSR
Owner: read, write, execute.
S_IRGRP, S_IWGRP, S_IXGRP
Group: read, write, execute.
S_IROTH, S_IWOTH, S_IXOTH
Others: read, write, execute.
The above define the access rights for a file and they are defined in the sys/stat.h header.
The function returns the file descriptor or in case of an error it returns the value -1. This call
is equivalent with:
open(path, O_WRONLY | O_CREAT | O_TRUNC, mod);
The argument path specifies the name of the file, while mod defines the access rights. If the
created file doesn’t exist, a new i-node is allocated and a link is made to this file from the
directory it was created in. The owner of the process that executes the call - given by the
effective UID and the effective GUID - must have writing permission in the directory. The
29
open file will have the access rights that were specified in the second argument (see umask,
too). The call returns the smallest file descriptor available. The file is opened for writing and
its initial size is 0. The access time and the modification time are updated in the i-node. If the
file exists (permission to search the directory is needed), it loses its contents and it will be
opened for writing. The ownership and the access permissions won’t be modified. The
second argument is ignored.
The function returns the number of bytes read, 0 for end of file (EOF) and -1 in case an error
occurred. It reads noct bytes from the open file referred by the fd descriptor and it puts it into
a bufferbuf. The pointer (current position) is incremented automatically after a reading that
certain amount of bytes. The process that executes a read operation waits until the system
puts the data from the disk into the buffer.
System call WRITE
For writing a certain number of bytes into a file starting from the current position we use
the write call. Its syntax is:
#include <unistd.h>
ssize_t write(int fd, const void* buf, size_t noct);
The function returns the number of bytes written and the value -1 in case of an error. It
writes noct bytes from the buffer buf into the file that has as its descriptor fd. It is interesting
to note that the actual writing onto the disk is delayed. This is done at the initiative of the
root, without informing the user when it is done. If the process that did the call or an other
process reads the data that haven’t been written on the disk yet, the system reads all this data
out from the cache buffers. The delayed writing is faster, but it has three disadvantages:
a) a disk error or a system error may cause loosing all the data
b) a process that had the initiative of a write operation cannot be informed in case
a writing error occurred
c) the physical order of the write operations cannot be controlled.
To eliminate these disadvantages, in some cases the O_SYNC is used. But as this slows down
the system and considering the reliability of today’s systems it is better to use the mechanism
which includes using cache buffers.
The function returns 0 in case of success and -1 in case of an error. At the termination of a
process an open file is closed anyway.
30
To position a pointer (that points to the current position) in an absolute or relative way can
be done by calling the lseek function. Read and write operations are done relative to the
current position in the file. The syntax for lseek is:
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int ref);
The function returns the displacement of the new current position from the beginning of the
file or -1 in case of an error. There isn’t done any I/O operation and the function doesn’t send
any commands to the disk controller. It ref is set to SEEK_SET the positioning is done
relative to the beginning of the file (the first byte in the file is at position 0). If ref is
SEEK_CUR the positioning is done relative to the current position. If ref is SEEK_END then
the positioning is done relative to the end of the file. The system
calls open, creat, write and read execute an lseek by default. If a file was opened using the
symbolic constant O_APPEND then an lseek call is made to the end of the file before a write
operation.
Theory:
Functions for working with directories
A directory can be read as a file by anyone whoever has reading permissions for it. Writing a
directory as a file can only be done by the kernel. The structure of the directory appears to the
user as a succession of structures named directory entries. A directory entry contains, among
other information, the name of the file and the i-node of this. For reading the directory entries
one after the other we can use the following functions:
#include <sys/types.h>
#include <dirent.h>
DIR* opendir(const char* pathname);
struct dirent* readdir(DIR* dp);
void rewinddir(DIR* dp);
int closedir(DIR* dp);
The opendir function opens a directory. It returns a valid pointer if the opening was
successful and NULL otherwise.
The readdir function, at every call, reads another directory entry from the current directory.
The first readdir will read the first directory entry; the second call will read the next entry
and so on. In case of a successful reading the function will return a valid pointer to a structure
of type dirent and NULL otherwise (in case it reached the end of the directory, for example).
The rewinddir function repositions the file pointer to the first directory entry (the beginning
of the directory).
The closedir function closes a previously opened directory. In case of an error it returns the
value -1.
The structure dirent is defined in the dirent.h file. It contains at least two elements:
struct dirent {
ino_t d_fileno; // i-node nr.
char d_name[MAXNAMLEN + 1]; // file name
}
31
THREADS MANAGEMENT:
32
*arg - pointer to argument of function. To pass multiple arguments, send a
o
pointer to a structure.
• Function call: pthread_join - wait for termination of another thread
int pthread_join(pthread_t th, void **thread_return);
Arguments:
o th - thread suspended until the thread identified by th terminates, either by
calling pthread_exit() or by being cancelled.
o thread_return - If thread_return is not NULL, the return value of th is stored in
the location pointed to by thread_return.
• Function call: pthread_exit - terminate the calling thread
void pthread_exit(void *retval);
Arguments:
retval - Return value of pthread_exit().
This routine kills the thread. The pthread_exit() function never returns. If the thread is
not detached, the thread id and return value may be examined from another thread by
using pthread_join().
Note: the return pointer *retval, must not be of local scope otherwise it would cease to
exist once the thread terminates.
• [C++ pitfalls]: The above sample program will compile with the GNU C and C++
compiler g++. The following function pointer representation below will work for C
but not C++. Note the subtle differences and avoid the pitfall below:
1 void print_message_function( void *ptr );
2 ...
3 ...
iret1 = pthread_create( &thread1, NULL, (void*)&print_message_function, (void*)
4 message1);
Thread Synchronization
The threads library provides three synchronization mechanisms:
• mutexes - Mutual exclusion lock: Block access to variables by other threads. This
enforces exclusive access by a thread to a variable or set of variables.
• joins - Make a thread wait till others are complete (terminated).
• condition variables - data type pthread_cond_t
Condition Variables:
A condition variable is a variable of type pthread_cond_t and is used with the appropriate
functions for waiting and later, process continuation. The condition variable mechanism
allows threads to suspend execution and relinquish the processor until some condition is true.
A condition variable must always be associated with a mutex to avoid a race condition
created by one thread preparing to wait and another thread which may signal the condition
before the first thread actually waits on it resulting in a deadlock. The thread will be
perpetually waiting for a signal that is never sent. Any mutex can be used, there is no explicit
link between the mutex and the condition variable.
Man pages of functions used in conjunction with the condition variable:
• Creating/Destroying:
o pthread_cond_init
o pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
o pthread_cond_destroy
33
• Waiting on condition:
o pthread_cond_wait - unlocks the mutex and waits for the condition variable
cond to be signaled.
o pthread_cond_timedwait - place limit on how long it will block.
• Waking thread based on condition:
o pthread_cond_signal - restarts one of the threads that are waiting on the
condition variable cond.
o pthread_cond_broadcast - wake up all threads blocked by the specified
condition
Thread Scheduling:
When this option is enabled, each thread may have its own scheduling properties. Scheduling
attributes may be specified:
• during thread creation
• by dynamically by changing the attributes of a thread already created
• by defining the effect of a mutex on the thread's scheduling when creating a mutex
• by dynamically changing the scheduling of a thread during synchronization
operations.
The threads library provides default values that are sufficient for most cases.
Thread Pitfalls:
• Race conditions: While the code may appear on the screen in the order you wish the
code to execute, threads are scheduled by the operating system and are executed at
random. It cannot be assumed that threads are executed in the order they are created.
They may also execute at different speeds. When threads are executing (racing to
complete) they may give unexpected results (race condition). Mutexes and joins must
be utilized to achieve a predictable execution order and outcome.
• Thread safe code: The threaded routines must call functions which are "thread safe".
This means that there are no static or global variables which other threads may
clobber or read assuming single threaded operation. If static or global variables are
used then mutexes must be applied or the functions must be re-written to avoid the
use of these variables. In C, local variables are dynamically allocated on the stack.
Therefore, any function that does not use static data or other shared resources is thread-
safe. Thread-unsafe functions may be used by only one thread at a time in a program
and the uniqueness of the thread must be ensured. Many non-reentrant functions return a
pointer to static data. This can be avoided by returning dynamically allocated data or
using caller-provided storage. An example of a non-thread safe function is strtok which
is also not re-entrant. The "thread safe" version is the re- entrant version strtok_r.
• Mutex Deadlock: This condition occurs when a mutex is applied but then not
"unlocked". This causes program execution to halt indefinitely. It can also be caused
by poor application of mutexes or joins. Be careful when applying two or more
mutexes to a section of code. If the first pthread_mutex_lock is applied and the
second pthread_mutex_lock fails due to another thread applying a mutex, the first
mutex may eventually lock all other threads from accessing data including the thread
which holds the second mutex. The threads may wait indefinitely for the resource to
become free causing a deadlock. It is best to test and if failure occurs, free the
resources and stall before retrying.
Thread Debugging:
34
• GDB:
o Debugging Programs with Multiple Threads
o GDB: Stopping and starting multi-thread programs
o GDB/MI: Threads commands
• DDD:
Semaphores
In its simplest form a semaphore is a location in memory whose value can be tested and set
by more than one process. The test and set operation is, so far as each process is concerned,
uninterruptible or atomic; once started nothing can stop it. The result of the test and set
operation is the addition of the current value of the semaphore and the set value, which can
be positive or negative. Depending on the result of the test and set operation one process
may have to sleep until the semphore's value is changed by another process. Semaphores
can be used to implement critical regions, areas of critical code that only one process at a
time should be executing.
Say you had many cooperating processes reading records from and writing records to a
single data file. You would want that file access to be strictly coordinated. You could use a
semaphore with an initial value of 1 and, around the file operating code, put two semaphore
operations, the first to test and decrement the semaphore's value and the second to test and
increment it. The first process to access the file would try to decrement the semaphore's
value and it would succeed, the semaphore's value now being 0. This process can now go
ahead and use the data file but if another process wishing to use it now tries to decrement
the semaphore's value it would fail as the result would be -1. That process will be
suspended until the first process has finished with the data file. When the first process has
finished with the data file it will increment the semaphore's value, making it 1 again. Now
the waiting process can be woken and this time its attempt to increment the semaphore will
succeed.
35
System V IPC semaphore objects each describe a semaphore array and Linux uses the
semid_ds data structure to represent this. All of the semid_ds data structures in the system
are pointed at by the semary, a vector of pointers. There are sem_nsems in each semaphore
array, each one described by a sem data structure pointed at by sem_base. All of the
processes that are allowed to manipulate the semaphore array of a System V IPC
semaphore object may make system calls that perform operations on them. The system call
can specify many operations and each operation is described by three inputs; the semaphore
index, the operation value and a set of flags. The semaphore index is an index into the
semaphore array and the operation value is a numerical value that will be added to the
current value of the semaphore. First Linux tests whether or not all of the operations would
succeed. An operation will succeed if the operation value added to the semaphore's current
value would be greater than zero or if both the operation value and the semaphore's current
value are zero. If any of the semaphore operations would fail Linux may suspend the
process but only if the operation flags have not requested that the system call is non-
blocking. If the process is to be suspended then Linux must save the state of the semaphore
operations to be performed and put the current process onto a wait queue. It does this by
building a sem_queue data structure on the stack and filling it out. The new sem_queue data
structure is put at the end of this semaphore object's wait queue (using the sem_pending and
sem_pending_last pointers). The current process is put on the wait queue in the sem_queue
data structure (sleeper) and the scheduler called to choose another process to run.
If all of the semaphore operations would have succeeded and the current process does not
need to be suspended, Linux goes ahead and applies the operations to the appropriate
members of the semaphore array. Now Linux must check that any waiting, suspended,
processes may now apply their semaphore operations. It looks at each member of the
operations pending queue (sem_pending) in turn, testing to see if the semphore operations
will succeed this time. If they will then it removes the sem_queue data structure from the
operations pending list and applies the semaphore operations to the semaphore array. It
wakes up the sleeping process making it available to be restarted the next time the
scheduler runs. Linux keeps looking through the pending list from the start until there is a
pass where no semaphore operations can be applied and so no more processes can be
woken.
There is a problem with semaphores, deadlocks. These occur when one process has altered
the semaphores value as it enters a critical region but then fails to leave the critical region
because it crashed or was killed. Linux protects against this by maintaining lists of
adjustments to the semaphore arrays. The idea is that when these adjustments are applied,
the semaphores will be put back to the state that they were in before the a process's set of
semaphore operations were applied. These adjustments are kept in sem_undo data
structures queued both on the semid_ds data structure and on the task_struct data structure
for the processes using these semaphore arrays.
Each individual semaphore operation may request that an adjustment be maintained. Linux
will maintain at most one sem_undo data structure per process for each semaphore array. If
the requesting process does not have one, then one is created when it is needed. The new
sem_undo data structure is queued both onto this process's task_struct data structure and
onto the semaphore array's semid_ds data structure. As operations are applied to the
semphores in the semaphore array the negation of the operation value is added to this
semphore's entry in the adjustment array of this process's sem_undo data structure. So, if
the operation value is 2, then -2 is added to the adjustment entry for this semaphore.
When processes are deleted, as they exit Linux works through their set of sem_undo data
structures applying the adjustments to the semaphore arrays. If a semaphore set is deleted,
the sem_undo data structures are left queued on the process's task_struct but the semaphore
36
array identifier is made invalid. In this case the semaphore clean up code simply discards
the sem_undo data structure.
SYNCHRONIZATION PROBLEMS:
The Producer Consumer Problem
The producer-consumer problem illustrates the need for synchronization in systems where
many processes share a resource. In the problem, two processes share a fixed-size buffer.
One process produces information and puts it in the buffer, while the other process
consumes information from the buffer. These processes do not take turns accessing the
buffer, they both work concurrently. Herein lies the problem. What happens if the producer
tries to put an item into a full buffer? What happens if the consumer tries to take an item
from an empty buffer?
In order to synchronize these processes, we will block the producer when the buffer is full,
and we will block the consumer when the buffer is empty. So the two processes, Producer
and Consumer, should work as follows:
(1) The producer must first create a new widget. (2) Then, it checks to see if the buffer is
full. If it is, the producer will put itself to sleep until the consumer wakes it up. A "wakeup"
will come if the consumer finds the buffer empty.(3) Next, the producer puts the new
widget in the buffer. If the producer goes to sleep in step (2), it will not wake up until the
buffer is empty, so the buffer will never overflow. (4) Then, the producer checks to see if
the buffer is empty. If it is, the producer assumes that the consumer is sleeping, an so it will
wake the consumer. Keep in mind that between any of these steps, an interrupt might occur,
allowing the consumer to run.
(1) The consumer checks to see if the buffer is empty. If so, the consumer will put itself to
sleep until the producer wakes it up. A "wakeup" will occur if the producer finds the buffer
empty after it puts an item into the buffer. (2) Then, the consumer will remove a widget
from the buffer. The consumer will never try to remove a widget from an empty buffer
because it will not wake up until the buffer is full.(3) If the buffer was full before it
removed the widget, the consumer will wake the producer. (4) Finally, the consumer will
consume the widget. As was the case with the producer, an interrupt could occur between
any of these steps, allowing the producer to run.
The Readers and Writers Problem
37
Wait until no writers
Access data base
Check out – wake up a waiting writer
– Writer()
Wait until no active readers or writers
Access database
Check out – wake up waiting readers or writer
– State variables (Protected by a lock called “lock”):
» int AR: Number of active readers; initially = 0
» int WR: Number of waiting readers; initially = 0
» int AW: Number of active writers; initially = 0
» int WW: Number of waiting writers; initially = 0
» Condition okToRead = NIL
» Conditioin okToWrite = NIL
A data set is shared among a number of concurrent processes
Readers– only read the data set; they do not perform any updates
Writers– can both read and write
Problem– allow multiple readers to read at the same time
Only one single writer can access the shared data at the same time
Several variations ofhow readers and writers are treated – all involve priorities
Shared Data
Data set
Semaphore mutex initialized to 1
Semaphore wrt initialized to 1
Integer readcount initialized to
The structure of a writer process
First variation– no reader kept waiting unless writer has permission to use shared
object
Second variation– once writer is ready, it performs write asap
Both may have starvation leading to even more variations
Problem is solved on some systems by kernel providing reader-writer locks
The Readers and Writers problem is useful for modeling processes which are
competing for a limited shared resource. A practical example of a Readers and
Writers problem is an airline reservation system consisting of a huge data base with
many processes that read and write the data. Reading information from the data base
will not cause a problem since no data is changed. The problem lies in writing
information to the data base. If no constraints are put on access to the data base, data
may change at any moment. By the time a reading process displays the result of a
request for information to the user, the actual data in the data base may have
changed. What if, for instance, a process reads the number of available seats on a
flight, finds a value of one, and reports it to the customer. Before the customer has a
chance to make their reservation, another process makes a reservation for another
customer, changing the number of available seats to zero.
In the following pages, we will look at solutions to this problem using semaphores,
monitors, and message passing.
38
• First Come First Serve (FCFS) Scheduling
• Shortest-Job-First (SJF) Scheduling
• Priority Scheduling
• Round Robin(RR) Scheduling
• Multilevel Queue Scheduling
First Come First Serve (FCFS)
• Jobs are executed on first come, first serve basis.
• Easy to understand and implement.
• Poor in performance as average wait time is high.
39
Wait time of each process is following
Process Wait Time : Service Time - Arrival Time
P0 3-0=3
P1 0-0= 0
P2 16 - 2 = 14
P3 8-3=5
Average Wait Time: (3+0+14+5) / 4 = 5.50
Priority Based Scheduling
• Each process is assigned a priority. Process with highest priority is to be
executed first and so on.
• Processes with same priority are executed on first come first serve basis.
• Priority can be decided based on memory requirements, time requirements
or any other resource requirement.
40
P3 0-0=0
Average Wait Time: (9+5+12+0) / 4 = 6.5
Round Robin Scheduling
• Each process is provided a fix time to execute called quantum.
• Once a process is executed for given time period. Process is preempted and
other process executes for given time period.
• Context switching is used to save states of preempted processes.
41
All the three methods have their own advantages and disadvantages as discussed
below:
1. Contiguous Allocation
In this scheme, each file occupies a contiguous set of blocks on the disk. For
example, if a file requires n blocks and is given a block b as the starting location,
then the blocks assigned to the file will be: b, b+1, b+2,……b+n-1. This means that
given the starting block address and the length of the file (in terms of blocks
required), we can determine the blocks occupied by the file.
The directory entry for a file with contiguous allocation contains
▪ Address of starting block
▪ Length of the allocated portion.
The file ‘mail’ in the following figure starts from the block 19 with length = 6 blocks.
Therefore, it occupies 19, 20, 21, 22, 23, 24 blocks.
Advantages:
▪ Both the Sequential and Direct Accesses are supported by this. For direct access, the address
of the kth block of the file which starts at block b can easily be obtained as (b+k).
▪ This is extremely fast since the number of seeks are minimal because of contiguous allocation
of file blocks.
Disadvantages:
▪ This method suffers from both internal and external fragmentation. This makes it inefficient in
terms of memory utilization.
▪ Increasing file size is difficult because it depends on the availability of contiguous memory at a
particular instance.
2. Linked List Allocation
In this scheme, each file is a linked list of disk blocks which need not be contiguous.
The disk blocks can be scattered anywhere on the disk.
The directory entry contains a pointer to the starting and the ending file block. Each
block contains a pointer to the next block occupied by the file.
The file ‘jeep’ in following image shows how the blocks are randomly distributed. The last
block (25) contains -1 indicating a null pointer and does not point to any other block.
42
Advantages:
▪ This is very flexible in terms of file size. File size can be increased easily since the system does
not have to look for a contiguous chunk of memory.
▪ This method does not suffer from external fragmentation. This makes it relatively better in
terms of memory utilization.
Disadvantages:
▪ Because the file blocks are distributed randomly on the disk, a large number of seeks are
needed to access every block individually. This makes linked allocation slower.
▪ It does not support random or direct access. We can not directly access the blocks of a file. A
block k of a file can be accessed by traversing k blocks sequentially (sequential access ) from
the starting block of the file via block pointers.
▪ Pointers required in the linked allocation incur some extra overhead.
3. Indexed Allocation
In this scheme, a special block known as the Index block contains the pointers to all
the blocks occupied by a file. Each file has its own index block. The ith entry in the
index block contains the disk address of the ith file block. The directory entry
contains the address of the index block as shown in the image:
43
Advantages:
▪ This supports direct access to the blocks occupied by the file and therefore provides fast
access to the file blocks.
▪ It overcomes the problem of external fragmentation.
Disadvantages:
▪ The pointer overhead for indexed allocation is greater than linked allocation.
▪ For very small files, say files that expand only 2-3 blocks, the indexed allocation would keep
one entire block (index block) for the pointers which is inefficient in terms of memory utilization.
However, in linked allocation we lose the space of only 1 pointer per block.
For files that are very large, single index block may not be able to hold all the
pointers.
Following mechanisms can be used to resolve this:
1. Linked scheme: This scheme links two or more index blocks together for holding the
pointers. Every index block would then contain a pointer or the address to the next index block.
2. Multilevel index: In this policy, a first level index block is used to point to the second level
index blocks which inturn points to the disk blocks occupied by the file. This can be extended to
3 or more levels depending on the maximum file size.
3. Combined Scheme: In this scheme, a special block called the Inode (information
Node) contains all the information about the file such as the name, size, authority, etc and the
remaining space of Inode is used to store the Disk Block addresses which contain the actual
file as shown in the image below. The first few of these pointers in Inode point to
the direct blocks i.e the pointers contain the addresses of the disk blocks that contain data of
the file. The next few pointers point to indirect blocks. Indirect blocks may be single indirect,
double indirect or triple indirect. Single Indirect block is the disk block that does not contain
the file data but the disk address of the blocks that contain the file data. Similarly, double
indirect blocks do not contain the file data but the disk address of the blocks that contain the
address of the blocks containing the file data.
44
Following Data structures are used to implement the Banker’s Algorithm:
Let ‘n’ be the number of processes in the system and ‘m’ be the number of
resources types.
Available :
▪ It is a 1-d array of size ‘m’ indicating the number of available resources of each type.
▪ Available[ j ] = k means there are ‘k’ instances of resource type Rj
Max :
▪ It is a 2-d array of size ‘n*m’ that defines the maximum demand of each process in a system.
▪ Max[ i, j ] = k means process Pi may request at most ‘k’ instances of resource type Rj.
Allocation :
▪ It is a 2-d array of size ‘n*m’ that defines the number of resources of each type currently
allocated to each process.
▪ Allocation[ i, j ] = k means process Pi is currently allocated ‘k’ instances of resource type Rj
Need :
▪ It is a 2-d array of size ‘n*m’ that indicates the remaining resource need of each process.
▪ Need [ i, j ] = k means process Pi currently allocated ‘k’ instances of resource type Rj
▪ Need [ i, j ] = Max [ i, j ] – Allocation [ i, j ]
Allocationi specifies the resources currently allocated to process Pi and
Needi specifies the additional resources that process Pi may still request to complete
its task.
Banker’s algorithm consist of Safety algorithm and Resource request algorithm
Safety Algorithm
The algorithm for finding out whether or not a system is in a safe state can be
described as follows:
1) Let Work and Finish be vectors of length ‘m’ and ‘n’ respectively.
Initialize: Work = Available
Finish[i] = false; for i=1, 2, 3, 4….n
2) Find an i such that both
a) Finish[i] = false
b) Needi <= Work if no such i exists goto step (4)
3) Work = Work + Allocation
Finish[i] = true
goto step (2)
4) if finish [i] = true for all i
then the system is in a safe state
Resource-Request Algorithm
Let Requesti be the request array for process Pi. Requesti [j] = k means process
Pi wants k instances of resource type Rj. When a request for resources is made by
process Pi, the following actions are taken:
1) If Requesti <= Needi
Goto step (2) ; otherwise, raise an error condition, since the process has exceeded its maximum
claim.
2) If Requesti <= Available Goto step (3); otherwise, P i must wait, since the resources are not
available.
3) Have the system pretend to have allocated the requested resources to process Pi by modifying the
state as
follows:
Available = Available – Requesti
Allocationi = Allocationi + Requesti
Needi = Needi– Requesti
45
PAGE REPLACEMENT ALGORITHMS:
Page replacement algorithms are the techniques using which Operating System decides
which memory pages to swap out, write to disk when a page of memory needs to be
allocated. Paging happens whenever a page fault occurs and a free page cannot be used for
allocation purpose accounting to reason that pages are not available or the number of free
pages is lower than required pages.
When the page that was selected for replacement and was paged out, is referenced again
then it has to read in from disk, and this requires for I/O completion. This process
determines the quality of the page replacement algorithm: the lesser the time waiting for page-
ins, the better is the algorithm. A page replacement algorithm looks at the limited information
about accessing the pages provided by hardware, and tries to select which pages should be
replaced to minimize the total number of page misses, while balancing it with the costs of
primary storage and processor time of the algorithm itself. There are many different page
replacement algorithms. We evaluate an algorithm by running it on a particular string of
memory reference and computing the number of page faults.
Reference String
The string of memory references is called reference string. Reference strings are generated
artificially or by tracing a given system and recording the address of each memory
reference. The latter choice produces a large number of data, where we note two things.
• For a given page size we need to consider only the page number, not the
entire address.
• If we have a reference to a page p, then any immediately following
references to page p will never cause a page fault. Page p will be in memory after
the first reference; the immediately following references will not fault.
• For example, consider the following sequence of addresses -
123,215,600,1234,76,96
• If page size is 100 then the reference string is 1,2,6,12,0,0
First In First Out (FIFO) algorithm
• Oldest page in main memory is the one which will be selected for
replacement.
• Easy to implement, keep a list, replace pages from the tail and add new
pages at the head.
46
• Replace the page that will not be used for the longest period of time . Use
the time when a page is to be used.
47
PROCEDURE TO RUN C PROGRAMS:
Step 1 : Use an editor, such as vi, ex, or ed to write the program. The name of the file
containing the program should end in .c.
main()
{
printf(“ welcome to GNEC “);
}
$ cc show.c
If the program is okay, the compiled version is placed in a file called a.out
$ a.out
48
CN PROGRAMS
PROGRAM No. 1
AIM: Understanding and using the following network utility commands like
ifconfig, netstat, ping, arp, telnet, ftp, finger, traceroute, whois.
AIM: Understanding and using of commands like ifconfig, netstat, ping, arp, telnet, ftp,
finger, traceroute, whois.
INTRODUCTION:
UNIX utilities are commands that, generally, perform a single task. It may be as simple as
printing the date and time, or a complex as finding files that match many criteria throughout a
directory hierarchy
IFCONFIG
The UNIX command ifconfig(short for interface configurator) serves to configure and
control TCP/IP network interfaces from a command line interface (CLI).
Common uses for ifconfig include setting an interface's IP address and netmask, and
disabling or enabling a given interface.
NETSTAT
netstat(network statistics) is a command-line tool that displays network connections (both
incoming and outgoing), routing tables, and a number of network interface statistics.
It is used for finding problems in the network and to determine the amount of traffic on the
network as a performance measurement.
Parameters
Parameters used with this command must be prefixed with a hyphen (-) rather than a slash (/).
-a: Displays all active TCP connections and the TCP and UDP ports on which the computer
is listening.
-e: Displays ethernet statistics, such as the number of bytes and packets sent and received.
This parameter can be combined with -s.
-f: Displays fully qualified domain names <FQDN> for foreign addresses.
-i: Displays network interfaces and their statistics (not available under Windows)
-n: Displays active TCP connections, however, addresses and port numbers are expressed
numerically and no attempt is made to determine names.
-o: Displays active TCP connections and includes the process ID (PID) for each connection.
-p Linux: Process: Show which processes are using which sockets
PING
49
Ping is a computer network tool used to test whether a particular host is reachable across an
IP network; it is also used to self-test the network interface card of the computer, or as a
speed test. It works by sending ICMP “echo request” packets to the target host and listening
for ICMP “echo response” replies. Ping does not estimate the round-trip time, as it does not
factor in the user's connection speed, but instead is used to record any packet loss, and print a
statistical summary when finished.
ARP
In computer networking, the Address Resolution Protocol (ARP) is the method for finding
a host's link layer (hardware) address when only its Internet Layer (IP) or some other
Network Layer address is known.
ARP has been implemented in many types of networks; it is not an IP-only or Ethernet-only
protocol. It can be used to resolve many different network layer protocol addresses to
interface hardware addresses, although, due to the overwhelming prevalence of IPv4 and
Ethernet, ARP is primarily used to translate IP addresses to Ethernet MAC addresses.
TELNET
Telnet (Telecommunication network) is a network protocol used on the Internet or local area
network (LAN) connections.
Typically, telnet provides access to a command-line interface on a remote machine.
The term telnet also refers to software which implements the client part of the protocol.
Telnet clients are available for virtually all platforms.
Protocol details:
Telnet is a client-server protocol, based on a reliable connection-oriented transport. Typically
this protocol is used to establish a connection to TCP port 23
FTP File Transfer Protocol (FTP):
FTP is a network protocol used to transfer data from one computer to another through a
network such as the Internet .FTP is a file transfer protocol for exchanging and manipulating
files over a TCP computer network. An FTP client may connect to an FTP server to
manipulate files on that server. FTP runs over TCP. It defaults to listen on port 21 for
incoming connections from FTP clients. A connection to this port from the FTP Client forms
the control stream on which commands are passed from the FTP client to the FTP server and
on occasion from the FTP server to the FTP client. FTP uses out-of-band control, which
means it uses a separate connection for control and data. Thus, for the actual file transfer to
take place, a different connection is required which is called the data stream.
FINGER
50
In computer networking, the Name/Finger protocol and the Finger user information
protocol are simple network protocols for the exchange of human-oriented status and user
information.
TRACEROUTE
Traceroute is a computer network tool used to determine the route taken by packets across
an IP network. An IPv6 variant, traceroute6, is also widely available. Traceroute is often
used for network troubleshooting. By showing a list of routers traversed, it allows the user to
identify the path taken to reach a particular destination on the network. This can help identify
routing problems or firewalls that may be blocking access to a site. Traceroute is also used by
penetration testers to gather information about network infrastructure and IP ranges around a
given host. It can also be used when downloading data, and if there are multiple mirrors
available for the same piece of data, one can trace each mirror to get a good idea of which
mirror would be the fastest to use.
WHO IS:
WHOIS (pronounced "who is"; not an acronym) is a query/response protocol which is
widely used for querying an official database in order to determine the owner of a domain
name, an IP address, or an autonomous system number on the Internet. WHOIS lookups were
traditionally made using a command line interface, but a number of simplified web-based
tools now exist for looking up domain ownership details from different databases. WHOIS
normally runs on TCP port 43.
The WHOIS system originated as a method that system administrators could use to look up
information to contact other IP address or domain name administrators (almost like a "white
pages").
51
PROGRAM No. 02
Aim: Implementation of Concurrent server service using connection oriented socket
system calls(Service: Daytime, Time)
INTRODUCTION: A connection-oriented server can be threaded so that it can serve multiple
clients concurrently/simultaneously. Such a server is said to be a concurrent server. When
the amount of time to service a request depends on the request itself, the server typically
handles it in a concurrent fashion.
Algorithms:
Server
1. Create a socket in internet domain using socket system call and then bind with the
server socket address by using bind system call.
2. Open a passive connection to table the connection request from client by using listen
call.
3. Take the connection request from the client, establish a connection to server using
accept.
4. A reply message is sent to client for the connection to be established and message to
be displayed.
5. Release the connection using close system call.
Client
Time Server:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <time.h>
52
main(int argc,char *argv[])
{
int sockfd,newsockfd,clilen,i,pid;
char buffer[512],a[50];
long t;
char *st;
struct sockaddr_in servaddr,cliaddr;
if(argc !=3)
{
printf("Usage:server <portno>\n");
exit(1);
}
sockfd=socket(AF_INET,SOCK_STREAM,0);
if(sockfd < 0)
{
printf("error server socket\n");
exit(1);
}
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr=inet_addr(argv[2]);
servaddr.sin_port=htons(atoi(argv[1]));
if(bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr)) < 0)
{
printf("error in bind");
exit(1);
}
if(listen(sockfd,5) < 0)
{
printf("listen");
exit(1);
}
for(; ;)
{
clilen=sizeof(cliaddr);
newsockfd=accept(sockfd,(struct sockaddr *)&cliaddr,&clilen);
if(newsockfd<0)
{
printf("accept");
exit(1);
}
if((pid==fork())<0)
{
printf("server failed to creat child");
exit(1);
}
else
{
// close(sockfd);
while(i=read(newsockfd,buffer,sizeof(buffer))!=0)
53
{
if(i<0)
{
printf("error in read");
exit(1);
}
t=time(&t);
st=(char *)ctime(&t);
strcpy(buffer,st);
i=strlen(st);
// read(newsockfd,a,50);
printf("server received %s %s",a,buffer);
// printf("\n%s%s",a,buffer);
if(write(newsockfd,buffer,i)!=i)
{
printf("error in write\n");
exit(1);
}
} /*while*/
//exit(0);
} /*pid*/
close(newsockfd);
}}
Output:
$ cc -o a tcpconserver.c
$ ./a 8050 172.0.5.48
server received Fri Apr 6 01:12:47 2018
server received Fri Apr 6 01:13:53 2018
Time Client:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
main(int argc,char *argv[])
{
int sockfd,i;
int read_frm_stdin,read_frm_sock;
char buffer[512];
struct sockaddr_in servaddr;
if(argc !=3)
{
printf("Client :Usage:client <portno> <server_name>\n");
exit(1);
}
sockfd=socket(AF_INET,SOCK_STREAM,0);
if(sockfd < 0)
{
perror("socket");
exit(1);
}
54
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr=inet_addr(argv[2]);
servaddr.sin_port=htons(atoi(argv[1]));
if(connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr)) < 0)
{
perror("connect");
exit(1);
}
write(sockfd,"the time and date is",50);
read(sockfd,buffer,sizeof(buffer));
printf("Client received the time and date is:%s\n",buffer);
close(sockfd);
}
Output:
For 1st Client:
$ cc -o aa tcptimeclient.c
$ ./aa 8050 172.0.5.48
Client received the time and date is:Fri Apr 6 01:12:47 2018
For 2nd Client:
$ cc -o bb tcptimeclient.c
$ ./bb 8050 172.0.5.48
Client received the time and date is:Fri Apr 6 01:13:53 2018
55
PROGRAM No. 3
Aim: Implementation of Iterative server using connection oriented socket system
calls(Service: Echo Service)
Iterativeserver:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
main(int argc,char *argv[])
{
int sockmain,sockcli,i,j;
int child;
char buffer[512];
struct sockaddr_in servaddr,cliaddr;
if(argc !=3)
{
printf("Usage:server <portno>\n");
exit(1);
}
sockmain=socket(AF_INET,SOCK_STREAM,0);
if(sockmain < 0)
{
printf("error in server socket");
exit(1);
}
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr=inet_addr(argv[2]);
servaddr.sin_port=htons(atoi(argv[1]));
56
// }
// if(child == 0)
// {
// close(sockmain);
read(sockcli,buffer,sizeof(buffer));
printf("server received message %s\n",buffer);
write(sockcli,buffer,sizeof(buffer));
close(sockcli);
}
Output:
$ cc -o aa iserver.c
$ ./aa 5040 172.0.5.48
server received message welcome
Iterativeclient:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
main(int argc,char *argv[])
{
int sockmain,sockcli,i,j;
int child;
char buffer[50],buffer1[50];
struct sockaddr_in servaddr,cliaddr;
if(argc !=3)
{
printf("Usage:client <portno> <server>\n");
exit(1);
}
sockmain=socket(AF_INET,SOCK_STREAM,0);
if(sockmain < 0)
{
printf("socket");
exit(1);
}
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr=inet_addr(argv[2]);
servaddr.sin_port=htons(atoi(argv[1]));
if(connect(sockmain,(struct sockaddr *)&servaddr,sizeof(servaddr)) < 0)
{
printf("error in connect\n");
exit(0);
}
// for(;;)
//{
printf("enter a message\n");
fgets(buffer,70,stdin);
write(sockmain,buffer,sizeof(buffer));
read(sockmain,buffer1,sizeof(buffer1));
printf("client recd the message %s\n",buffer1);
close(sockmain);
57
}
Output:
$ cc -o bb iclient.c
$ ./bb 5040 172.0.5.48
enter a message
welcome
client recd the message welcome
58
PROGRAM No. 4
Aim: Implementation of Concurrent server using connection less socket system calls(Service:
Echo server)
INTRODUCTION: The server knows ahead of time about how long it takes to handle eachrequest and
server process handles each request itself is known as iterative server.
Connection less Implementation
Server
➢ Create a UDP Socket.
➢ Fill in the socket address structure (with server information)
➢ Specify the port where the service will be defined to be used by client.
➢ Bind the address and port using bind() system call.
➢ Receive a message from the Client using recvfrom() system call.
➢ Send the result of the request made by the client using sendto() system call.
Client
➢ Create a UDP Socket.
➢ Fill in the socket address structure (with server information)
➢ Specify the port of the Server, where it is providing service
➢ For echo server, send a message to the server to be echoed using sendto() system call.
➢ Receive the result of the request made to the server using recvfrom() system call.
➢ Write the result thus obtained on the standard output.
59
}
servaddr.sin_family=AF_INET;
servaddr.sin_addr.s_addr=inet_addr("172.0.5.48");
servaddr.sin_port=htons(atoi(argv[1]));
if(bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr))<0 )
{
printf("can't bind");
exit(0);
}
while(1)
{
clilen=sizeof(cliaddr);
if(recvfrom(sockfd,a,50,0,(struct sockaddr *)&cliaddr,&clilen) <0)
{
printf("error in recvfrom\n");
exit(0);
}
printf("server recd the message:%s\n",a);
pid=fork();
if(pid ==0)
{
//printf("server received message:%s",a);
togglecase(a,cnt);
if(sendto(sockfd,a,50,0,(struct sockaddr*)&cliaddr,sizeof(cliaddr) )<0)
{
printf("error in sendto\n");
exit(0);
}
}
}
close(sockfd);
}
void togglecase(char *a,int cnt)
{
int i;
for(i=0;i<cnt;i++)
{
if((a[i] >='A') && (a[i] <= 'Z'))
a[i] += 0X20;
else if((a[i] >='a') && (a[i] <='z'))
a[i] -= 0X20;
}
}
Output:
$ cc -o ab clconserver.c
$ ./ab 4050
server recd the message: hi
server recd the message: hello
Connectionless Concurrent Client:
#include<stdio.h>
60
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
int main(int argc,char *argv[])
{
int sockfd,servlen;
char a[50],a1[50];
struct sockaddr_in servaddr,cliaddr;
sockfd=socket(AF_INET,SOCK_DGRAM,0);
if(argc!=3)
{
printf("usage:<client> <port> <ipaddress>\n");
exit(0);
}
if(sockfd < 0)
{
printf("can't bind");
exit(0);
}
servaddr.sin_family=AF_INET;
servaddr.sin_addr.s_addr=inet_addr(argv[2]);
servaddr.sin_port=htons(atoi(argv[1]));
cliaddr.sin_family=AF_INET;
cliaddr.sin_addr.s_addr=inet_addr(argv[2]);
cliaddr.sin_port=htons(0);
bind(sockfd,(struct sockaddr*)&cliaddr,sizeof(cliaddr));
printf("enter a mess");
fgets(a,50,stdin);
servlen=sizeof(servaddr);
sendto(sockfd,a,50,0,(struct sockaddr*)&servaddr,servlen);
recvfrom(sockfd,a1,50,0,(struct sockaddr*)&servaddr,&servlen);
printf("client received msg:%s",a1);
}
Output:
For 1st Client:
$ cc -o aa clconclient.c
$ ./aa 4050 172.0.5.48
enter a mess hi
client received msg: HI
For 2st Client:
$ cc -o vv clconclient.c
$ ./vv 4050 172.0.5.48
enter a mess hello
client received msg: HELLO
61
PROGRAM No. 5
Aim: Implementation of Iterative server using connection less socket system calls
(Service: Student Grade)
Gradeserver:
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
void togglecase(char *a,int cnt);
int main(int argc,char *argv[])
{
int sockfd,newsockfd,clilen,n;
struct sockaddr_in servaddr,cliaddr;
char a[50];
int cnt=80;
int pid;
sockfd=socket(AF_INET,SOCK_DGRAM,0);
if(argc!=2)
{
printf("Usage: <server> <portno>");
exit(0);
}
if(sockfd < 0)
{
printf("can't create");
exit(0);
}
servaddr.sin_family=AF_INET;
servaddr.sin_addr.s_addr=inet_addr("172.0.5.48");
servaddr.sin_port=htons(atoi(argv[1]));
if(bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr))<0 )
{
printf("can't bind");
exit(0);
}
//while(1)
//{
clilen=sizeof(cliaddr);
if(recvfrom(sockfd,a,50,0,(struct sockaddr *)&cliaddr,&clilen) <0)
{
printf("error in recvfrom\n");
exit(0);
}
printf("server recd the message:%s\n",a);
// pid=fork();
// if(pid ==0)
62
//{
//printf("server received message:%s",a);
togglecase(a,cnt);
if(sendto(sockfd,a,50,0,(struct sockaddr*)&cliaddr,sizeof(cliaddr) )<0)
{
printf("error in sendto\n");
exit(0);
}
// }
//}
close(sockfd);
}
void togglecase(char *a,int cnt)
{
int i;
int k=atoi(a);
if(k>=60)
strcpy(a,"you have passed in a grade \n");
else if((k>=50) && (k<60))
strcpy(a,"you have passed in b grade \n");
else if((k>=35) && (k<50))
strcpy(a,"you have passed in c grade \n");
else
strcpy(a,"you have passed in d grade \n");
//printf("%d",k);
for(i=0;i<cnt;i++)
{
if((a[i] >='A') && (a[i] <= 'Z'))
a[i] += 0X20;
else if((a[i] >='a') && (a[i] <='z'))
a[i] -= 0X20;
}
}
Output:
$ vi Gradeserver.c
$ cc -o b Gradeserver.c
$ ./b 8000
server recd the message:80
Gradeclient:
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
int main(int argc,char *argv[])
{
63
int sockfd,servlen;
char a[50],a1[50];
struct sockaddr_in servaddr,cliaddr;
sockfd=socket(AF_INET,SOCK_DGRAM,0);
if(argc!=3)
{
printf("usage:<client> <port> <ipaddress>\n");
exit(0);
}
if(sockfd < 0)
{
printf("can't bind");
exit(0);
}
servaddr.sin_family=AF_INET;
servaddr.sin_addr.s_addr=inet_addr(argv[2]);
servaddr.sin_port=htons(atoi(argv[1]));
cliaddr.sin_family=AF_INET;
cliaddr.sin_addr.s_addr=inet_addr(argv[2]);
cliaddr.sin_port=htons(0);
bind(sockfd,(struct sockaddr*)&cliaddr,sizeof(cliaddr));
printf("enter a Percentage:");
fgets(a,50,stdin);
servlen=sizeof(servaddr);
sendto(sockfd,a,50,0,(struct sockaddr*)&servaddr,servlen);
recvfrom(sockfd,a1,50,0,(struct sockaddr*)&servaddr,&servlen);
printf("client received msg:%s",a1);
}
Output:
$ cc -o a Gradeclient.c
$ ./a 8000 172.0.5.48
enter a Percentage:80
client received msg:YOU HAVE PASSED IN A GRADE
64
PROGRAM No: 6
AIM : To implement a program for packet capturing and filtering between the server and the client systems.
ALGORITHM
Server
▪ Set server port address.
▪ Using socket function, create a socket for server by specifying server port.
▪ Allocate a buffer size.
Client
▪ Set client machine address and server port address.
▪ Allocate buffer use TCP for receiving message from server to client.
▪ Read the file from the server.
PROGRAM: Server
#include<stdio.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<errno.h>
int main()
intsrFd,CIFD,len;
65
structsockaddr_inserver,client;
charbuf[SIZE],buf1[SIZE];
intn,j;
FILE *fp,*fp1;
srFd=socket(AF_INET,SOCK_STREAM,0);
if(srFd<0)
exit(0);
bzero(&server,sizeof(server));
server.sin_family=AF_INET;
server.sin_port=htons(2200);
server.sin_addr.s_addr=htons(INADDR_ANY);
if(bind(srFd,(structsockaddr *)&server,sizeof(server))<0)
close(srFd);
exit(0);
if(listen(srFd,1)<0)
close(CIFD);
66
exit(0);
len=sizeof(client);
CIFD=accept(srFd,(structsockaddr *)&client,&len);
if(CIFD<0)
close(CIFD);
close(srFd);
exit(0);
bzero(&buf,sizeof(buf));
if((n=recv(CIFD,&buf,SIZE,0))<0)
close(srFd);
close(CIFD);
exit(0);
buf[n-1]=NULL;
if((n=send(CIFD,buf,strlen(buf),0))<0)
67
{
printf(“\n Error”);
close(CIFD);
exit(0);
close(srFd);
close(CIFD);
exit(0);
Client
#include<stdio.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<string.h>
int main()
int CIFD;
structsockaddr_in client;
charbuf[SIZE];
int n;
if((CIFD=socket(AF_INET,SOCK_STREAM,0))<0)
68
exit(0);
bzero(&client,sizeof(client));
client.sin_family=AF_INET;
client.sin_port=htons(2200);
inet_pton(AF_INET,”127.0.0.1″,&client.sin_addr);
if(connect(CIFD,(structsockaddr *)&client,sizeof(client))<0)
{
close(CIFD);
exit(0);
bzero(&buf,sizeof(buf));
if(fgets(buf,SIZE,stdin)==NULL)
close(CIFD);
exit(0);
if(send(CIFD,buf,strlen(buf),0)<0)
close(CIFD);
69
exit(0);
bzero(&buf,sizeof(buf));
if((n=recv(CIFD,buf,SIZE,0))<0)
exit(0);
buf[n]=NULL;
close(CIFD);
exit(0);}
OUTPUT
Client
[student@localhost ~]$ ./a.out
Connection Enabled
Enter Source File
Tps.c
Client Message Sent
Destination Filename From Server tps.c
Server
[student@localhost ~]$ ./a.out
70
PROGRAM No. 7
AIM : To write a C-program to implement Client – Server communication using RPC.
DESCRIPTION
A remote procedure call (RPC) is an inter-process communication that allows a computer program to cause a
subroutine or procedure to execute in another address space (commonly on another computer on a shared
network) without the programmer explicitly coding the details for this remote interaction.
In RPC, the sender makes a request in the form of a procedure, function, or method call. RPC translates these
calls into requests sent over the network to the intended destination.
The RPC recipient then processes the request based on the procedure name and argument list, sending a
response to the sender when complete.
The process is initiated by the client, which sends a request message to a known remote server to execute a
specified procedure with supplied parameters.
The remote server sends a response to the client, and the application continues its process.
While the server is processing the call, the client is blocked, it waits until the server has finished processing
before resuming execution.
Algorithm
Step 1:
write your own RPC specification file ―gcd.xǁ
Step 2:
Use rpcgen to generate the files you need
(i.e gcd.h, gcd_svc.c, gcd_xdr.c, gcd_clnt.c)
$rpcgen gcd.x
Step 3:
Use rpcgen to generate sample server program
$rpcgen –Ss gcd.x > gcd_server.c
Step 4:
Use rpcgen to generate sample client program
$rpcgen –Sc gcd.x > gcd_client.c
Step 5:
Modify your sample server and client programs
Step 6:
Use cc to compile your server program (gcd_server.c)
$ cc –o gcd_server gcd_server.c gcd_svc.c gcd_xdr.c –lnsl
Step 7:
Use cc to compile your client program (gcd_client.c)
$ cc –o gcd_client gcd_client.c gcd_clnt.c gcd_xdr.c –lnsl
Step 8:
Run your server program
$./gcd_server &
Step 9:
Run your client program $./gcd_client <ip address> <number 1> <number 2>
Program for gcd.x:
struct num
{
long a;
long b;
};
71
program gcd_prog
{
version gcd_vers
{
long gcd_fun(num)=1;
}=1;
}=0x30000001;
Program for gcd_server:
#include "gcd.h"
int gcd(int a,int b)
{
if(b==0)
return a;
return gcd(b,a%b);
}
long *
gcd_fun_1_svc(num *argp, struct svc_req *rqstp)
{
static long result;
result=gcd((*argp).a,(*argp).b);
/*
* insert server code here
*/
return &result;
}
Program for gcd_client:
#include "gcd.h"
void
gcd_prog_1(char *host,num number)
{
CLIENT *clnt;
long *result_1;
num gcd_fun_1_arg;
gcd_fun_1_arg.a=number.a;
gcd_fun_1_arg.b=number.b;
#ifndef DEBUG
clnt = clnt_create (host, gcd_prog, gcd_vers, "udp");
if (clnt == NULL) {
clnt_pcreateerror (host);
exit (1);
}
#endif /* DEBUG */
result_1 = gcd_fun_1(&gcd_fun_1_arg, clnt);
if (result_1 == (long *) NULL) {
clnt_perror (clnt, "call failed");
}
printf("gcd is %d",*result_1);
72
#ifndef DEBUG
clnt_destroy (clnt);
#endif /* DEBUG */
}
int
main (int argc, char *argv[])
{
char *host;
num n;
if (argc < 4) {
printf ("usage: %s server_host\n", argv[0]);
exit (1);
}
=atol(argv[2]);
=atol(argv[3]);
host = argv[1];
gcd_prog_1 (host,n);
exit (0);
}
Output:
$ vi gcd.x
$ rpcgen gcd.x
$ rpcgen -Ss gcd.x > gcd_server.c
$ rpcgen -Sc gcd.x > gcd_client.c
$ vi gcd_server.c
$ vi gcd_client.c
$ cc -o gcd_server gcd_server.c gcd_svc.c gcd_xdr.c -lnsl
$ cc -o gcd_client gcd_client.c gcd_clnt.c gcd_xdr.c -lnsl
$ ./gcd_server &
[1] 1966
Output 1: $ ./gcd_client 172.0.5.48 4 2
gcd is 2
73
PROGRAM No. 8
AIM: To write a C program to perform sliding window.
DESCRIPTION
A sliding window frame of data is sent from server to client. If that frame is received correctly at the client
then acknowledgement signal is sent to server. Otherwise negative acknowledgement is sent. Frame size for
the sliding window is provided by the user. Then the frame of data is sent with ACK signal or NACK signal.
A sliding window protocol is a feature of packet-based data transmission protocol. Sliding window protocols
are used where reliable in-order delivery of packets is required, such as in the data link layer of OSI model as
well as in the TCP.
A data frame is an aggregate of numerous, partly overlapping collections of data and metadata that have been
derived from massive amounts of network activity such as content production, consumption, and other user
behaviour.
ALGORITHM
Start the program.
Get the frame size from the user.
To create the frame based on the user request.
To send frames to server from the client side.
If your frames reach the server it will send ACK signal to client otherwise it will send NACK signal to client.
Stop the program.
PROGRAM: Sliding window protocol
Client:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct mymsg buf
{
long mtype;
char mtext[25];
};
FILE *fp;
int main()
{
struct mymsgbufbuf;
int msgid;
int i=0,s;
int count=0,frmsz;
int a[100];
char d;
if((msgid=msget(89,IPC_CREAT|0666))==-1)
{
printf("\n RROR IN MSGGET");
exit(0);
}
printf("\n Enter the frame size:"); scanf("%d",&frmsz);
74
if((fp=fopen("check","r"))==NULL) printf("\n FILE NOT OPENED");
else
printf("\n FILE OPENED"); while(!feof(fp))
{
d=getc(fp);
a[i]=d; i++;
}
s=i;
for(i=0;i<frmsz;i++)
//print from the check file printf("\t %c",a[i]); for(i=0;i<frmsz;i++)
{
if((msgrcv(msgid,&buf,sizeof(buf),0,1))==-1)
{
printf("\n ERROR IN MSGRCV"); exit(0);
}
printf("\n RECEIVED FRAMES ARE:%c",buf.mtext[i]);
}
for(i=0;i<frmsz;i++)
{
if(a[i]==buf.mtext[i]) count++;
}
if(count==0)
{
printf("\n FRAMES WERE NOT RECEIVED IN CORRECT SEQ");
exit(0);
}
if(count==frmsz)
{
printf("\n FRAMES WERE RECEIVED IN CORRECT SEQ");
} else
{
printf("\n FRAMES WERE NOT RECEIVED IN CORRECT SEQ");
}
}
//Sliding Window Protocol -Server
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct mymsgbuf
{
long mtype; char mtext[25];
};
FILE *fp;
int main()
75
{
struct mymsgbuf buf;
int si,ei,sz;
int msgid;
int i=0,s;
int a[100];
char d;
if((fp=fopen("send","r"))==NULL)
printf("\n FILE NOT OPENED");
else
printf("\n FILE OPENED");
printf("\n Enter starting and ending index of frame array:");
scanf("%d%d",&si,&ei); sz=ei-si; if((msgid=msgget(89,IPC_CREAT|0666))==-1)
{
printf("\n ERROR IN MSGGET"); exit(0);
}
while(!feof(fp))
{
d=getc(fp); a[i]=d; i++;
}
s=i;
buf.mtype=1;
for(i=si;i<=ei;i++)
{
buf.mtext[i]=a[i];
}
for(i=si;i<=ei;i++) //the frames to be sent
printf("\t %c",buf.mtext[i]); for(i=0;i<=sz;i++)
{
if((msgsnd(msgid,&buf,sizeof(buf),0))==-1)
{
printf("\n ERROR IN MSGSND"); exit(0);
}
}
printf("\n FRAMES SENT");
return 0;
}
OUTPUT:
Enter the frame size : 5 File opened
Enter starting & ending index of frame array : 0 9 Frames sent
Received frames are: 0 3 6 7 9
RESULT:
Thus the C-program for performing client server based sliding window protocol was executed and output
verified using various samples.
76
PROGRAM No. 9:
AIM: To create simple topology using Network Simulator – 2.
ALGORITHM:
Step 1: Start network simulator OTCL editor.
Step 2: Create new simulator using set ns [new Simulator] syntax Step 3: Create Trace route to Network
Animator
set nf [open out.nam w]
$ns namtrace-all $nf
Step 4: Create procedure to trace all path
proc create_testnet {} { global s1 s2 r1 k1
set s1 [$ns node]
set s2 [$ns node]
set r1 [$ns node]
set k1 [$ns node]
}
Step 5: Create full duplex connection using
$ns duplex-link $s1 $r1 8Mb 5ms drop-tail
$ns duplex-link $s2 $r1 8Mb 5ms drop-tail
set L [ns_duplex $r1 $k1 800Kb 100ms drop-tail]
Step 4: Connect with TCP and SINK command.
$ns connect $tcp $sink
Step 5: Run and Execute the program.
$ns run
PROGRAM:
set ns [new Simulator]
set nf [open udp.nam w]
$ns namtrace-all
$nf set tf [open out.tr w]
$ns trace-all $tf
proc create_testnet {} { global s1 s2 r1 k1
set s1 [$ns node]
set s2 [$ns node]
set r1 [$ns node]
set k1 [$ns node]
}
$ns duplex-link $s1 $r1 8Mb 5ms drop-tail
$ns duplex-link $s2 $r1 8Mb 5ms drop-tail
set L [ns_duplex $r1 $k1 800Kb 100ms drop-tail] [lindex $L 0] set queue-limit 6
[lindex $L 1] set queue-limit 6
$ns run
OUTPUT:
77
RESULT:
Thus the program for implementing UDP was executed using NS-2 and output verified using Network
Animator.
78
PROGRAM No. 10
AIM: To implement User Datagram Protocol (UDP) using NS-2
ALGORITHM:
Step 1: Start network simulator OTCL editor.
Step 2: Create new simulator using set ns [new Simulator] syntax Step 3: Create procedure to trace all path
proc finish {} {
global ns nf tf
$ns flush-trace close $nf
close $tf
exec nam udp.nam & exit 0 }
Step 4: Connect with TCP and SINK command.
$ns connect $tcp $sink
Step 5: Run and Execute the program.
$ns run
PROGRAM:
set ns [new Simulator]
set nf [open udp.nam w]
$ns namtrace-all
$nf set tf [open out.tr w]
$ns trace-all $tf proc finish {} {
global ns nf tf
$ns flush-trace close $nf close $tf
exec nam udp.nam & exit 0
}
set n0 [$ns node]
set n1 [$ns node]
set n2 [$ns node]
set n3 [$ns node]
set n4 [$ns node]
set n5 [$ns node]
$ns duplex-link $n0 $n4 1Mb 50ms DropTail
$ns duplex-link $n1 $n4 1Mb 50ms DropTail
$ns duplex-link $n2 $n5 0.1Mb 1ms DropTail
$ns duplex-link $n3 $n5 1Mb 1ms DropTail
$ns duplex-link $n4 $n5 1Mb 50ms DropTail
$ns duplex-link-op $n2 $n5 queuePos 1 set tcp [new Agent/UDP]
$ns attach-agent $n0 $tcp set sink [new Agent/Null]
$ns attach-agent $n2 $sink
$ns connect $tcp $sink
set ftp [new Application/Traffic/CBR]
$ftp attach-agent $tcp
$ns at 0.0 "$ftp start"
$ns at 2.5 "$ftp stop"
$ns at 3 "finish"
$ns run
OUTPUT:
79
RESULT:
Thus the program for implementing UDP was executed using NS-2 and output verified using Network
Animator.
80
PROGRAM No. 11
AIM: To implement Transmission Control Protocol (TCP) using NS-2
ALGORITHM:
Step 1: Start network simulator OTCL editor.
Step 2: Create new simulator using set ns [new Simulator] syntax Step 3: Create procedure to trace all path
proc finish {} {
global ns nf tf
$ns flush-trace close $nf
close $tf
exec nam tcp.nam & exit 0}
Step 4: Connect with TCP and SINK command.
$ns connect $tcp $sink
Step 5: Run and Execute the program.
$ns run
PROGRAM:
set ns [new Simulator] set nf [open tcp.nam w]
$ns namtrace-all $nf set tf [open out.tr w]
$ns trace-all $tf proc finish {} {
global ns nf tf
$ns flush-trace close $nf
close $tf
exec nam tcp.nam & exit 0
}
set n0 [$ns node]
set n1 [$ns node]
set n2 [$ns node]
set n3 [$ns node]
set n4 [$ns node]
set n5 [$ns node]
$ns duplex-link $n0 $n4 1Mb 50ms DropTail
$ns duplex-link $n1 $n4 1Mb 50ms DropTail
$ns duplex-link $n2 $n5 1Mb 1ms DropTail
$ns duplex-link $n3 $n5 1Mb 1ms DropTail
$ns duplex-link $n4 $n5 1Mb 50ms DropTail
$ns duplex-link-op $n4 $n5 queuePos 0.5 set tcp [new Agent/TCP]
$ns attach-agent $n0 $tcp
set sink [new Agent/TCPSink]
$ns attach-agent $n2 $sink
$ns connect $tcp $sink
set ftp [new Application/FTP]
$ftp attach-agent $tcp
$ns at 0.0 "$ftp start"
$ns at 2.5 "$ftp stop"
$ns at 3 "finish"
$ns run
OUTPUT:
81
RESULT:
Thus the program for implementing TCP was executed using NS-2 and output verified using Network
Animator.
82
PROGRAM No. 12
AIM: To compare various MAC Protocols performance using NS-2
ALGORITHM:
Step 1: Start network simulator OTCL editor.
Step 2: Create new simulator using set ns [new Simulator] syntax Step 3: Create Trace route to Network
Animator
set nf [open out.nam w]
$ns namtrace-all $nf
Step 4: Create procedure to trace all path
proc finish {} {
global ns nf
$ns flush-trace
#Close the NAM trace file close $nf
#Execute NAM on the trace file exec nam out.nam &
exit 0
}
Step 4: Connect with TCP and SINK command.
$ns connect $tcp $sink
Step 5: Setup a FTP over TCP connection
set ftp [new Application/FTP]
$ftp attach-agent $tcp
$ftp set type_ FTP
Step 6: Setup a CBR over UDP connection
set cbr [new Application/Traffic/CBR]
$cbr attach-agent $udp
$cbr set type_ CBR
Step 7: Run and Execute the program.
$ns run
PROGRAM:
#Create a simulator object set ns [new Simulator]
#Define different colors for data flows (for NAM)
$ns color 1 Blue
$ns color 2 Red
#Open the NAM trace file set nf [open out.nam w]
$ns namtrace-all $nf #Define a 'finish' procedure proc finish {} {
global ns nf
$ns flush-trace
#Close the NAM trace file close $nf
#Execute NAM on the trace file exec nam out.nam &
exit 0
83
I.T Dept., MVSREC CN/OS Lab
}
#Create four nodes set n0 [$ns node]
set n1 [$ns node]
set n2 [$ns node]
set n3 [$ns node]
#Create links between the nodes
$ns duplex-link $n0 $n2 2Mb 10ms DropTail
$ns duplex-link $n1 $n2 2Mb 10ms DropTail
$ns duplex-link $n2 $n3 1.7Mb 20ms DropTail #Set Queue Size of link (n2-n3) to 10
$ns queue-limit $n2 $n3 10 #Give node position (for NAM)
$ns duplex-link-op $n0 $n2 orient right-down
$ns duplex-link-op $n1 $n2 orient right-up
$ns duplex-link-op $n2 $n3 orient right #Monitor the queue for link (n2-n3). (for NAM)
$ns duplex-link-op $n2 $n3 queuePos 0.5 #Setup a TCP connection
set tcp [new Agent/TCP]
$tcp set class_ 2
$ns attach-agent $n0 $tcp
set sink [new Agent/TCPSink]
$ns attach-agent $n3 $sink
$ns connect $tcp $sink
$tcp set fid_ 1
#Setup a FTP over TCP connection set ftp [new Application/FTP]
$ftp attach-agent $tcp
$ftp set type_ FTP #Setup a UDP connection set udp [new Agent/UDP]
$ns attach-agent $n1 $udp set null [new Agent/Null]
$ns attach-agent $n3 $null
$ns connect $udp $null
$udp set fid_ 2
#Setup a CBR over UDP connection set cbr [new Application/Traffic/CBR]
$cbr attach-agent $udp
$cbr set type_ CBR
$cbr set packet_size_ 1000
$cbr set rate_ 1mb
$cbr set random_ false
#Schedule events for the CBR and FTP agents
$ns at 0.1 "$cbr start"
$ns at 1.0 "$ftp start"
$ns at 4.0 "$ftp stop"
$ns at 4.5 "$cbr stop"
#Detach tcp and sink agents (not really necessary)
$ns at 4.5 "$ns detach-agent $n0 $tcp ; $ns detach-agent $n3 $sink" #Call the finish procedure after 5
seconds of simulation time
$ns at 5.0 "finish"
#Print CBR packet size and interval
puts "CBR packet size = [$cbr set packet_size_]" puts "CBR interval = [$cbr set interval_]"
#Run the simulation
$ns run
OUTPUT:
RESULT:
84
I.T Dept., MVSREC CN/OS Lab
Thus the MAC Protocols performance compared by using NS-2 and output verified by using Network
Animator.
85
I.T Dept., MVSREC CN/OS Lab
PROGRAM No. 13
AIM: To compare various Routing Protocols performance using NS-2
ALGORITHM:
Step 1: Start network simulator OTCL editor.
Step 2: Create new simulator using set ns [new Simulator] syntax Step 3: Create Trace route to Network
Animator
set nf [open out.nam w]
$ns namtrace-all $nf
Step 4: Create procedure to trace all path
proc finish {} {
global ns
$ns flush-trace
puts "running nam..." exec nam out.nam & exit 0
}
Step 4: Connect with UDP and CBR command.
set cbr1 [new Application/Traffic/CBR] set udp1 [new Agent/UDP]
$cbr1 attach-agent $udp1
$udp1 set dst_ 0x8002
$udp1 set class_ 1
$ns attach-agent $n3 $udp1
Step 5: Setup a new agent for performing Multicast Routing procedure
set rcvr [new Agent/LossMonitor] #$ns attach-agent $n3 $rcvr
Step 6: Create a group and start services
$ns at 1.2 "$n2 join-group $rcvr 0x8002"
$ns at 1.25 "$n2 leave-group $rcvr 0x8002"
$ns at 1.3 "$n2 join-group $rcvr 0x8002"
$ns at 1.35 "$n2 join-group $rcvr 0x8001"
$ns at 1.0 "$cbr0 start"
$ns at 1.1 "$cbr1 start"
$ns at 2.0 "finish"
Step 7: Run and Execute the program.
$ns run
PROGRAM:
set ns [new Simulator]
$ns multicast
set f [open out.tr w]
$ns trace-all $f
$ns namtrace-all [open out.nam w]
$ns color 1 red
# prune/graft packets
$ns color 30 purple
$ns color 31 green set n0 [$ns node]
set n1 [$ns node]
set n2 [$ns node]
set n3 [$ns node]
# Use automatic layout
$ns duplex-link $n0 $n1 1.5Mb 10ms DropTail
$ns duplex-link $n1 $n2 1.5Mb 10ms DropTail
$ns duplex-link $n1 $n3 1.5Mb 10ms DropTail
$ns duplex-link-op $n0 $n1 orient right
$ns duplex-link-op $n1 $n2 orient right-up
$ns duplex-link-op $n1 $n3 orient right-down
$ns duplex-link-op $n1 $n3 orient right-down
$ns duplex-link-op $n0 $n1 queuePos 0.5
86
I.T Dept., MVSREC CN/OS Lab
set mrthandle [$ns mrtproto DM {}]
set cbr0 [new Application/Traffic/CBR] set udp0
[new Agent/UDP]
$cbr0 attach-agent $udp0
$ns attach-agent $n1 $udp0
$udp0 set dst_ 0x8001
set cbr1 [new Application/Traffic/CBR] set udp1
[new Agent/UDP]
$cbr1 attach-agent $udp1
$udp1 set dst_ 0x8002
$udp1 set class_ 1
$ns attach-agent $n3 $udp1
set rcvr [new Agent/LossMonitor] #$ns
attach-agent $n3 $rcvr
$ns at 1.2 "$n2 join-group $rcvr 0x8002"
$ns at 1.25 "$n2 leave-group $rcvr 0x8002"
$ns at 1.3 "$n2 join-group $rcvr 0x8002"
$ns at 1.35 "$n2 join-group $rcvr 0x8001"
$ns at 1.0 "$cbr0 start"
$ns at 1.1 "$cbr1 start"
$ns at 2.0 "finish" proc finish {} {
global ns
$ns flush-trace
puts "running nam..." exec nam out.nam & exit 0
}
$ns run
OUTPUT:
RESULT:
Thus the Routing Protocols performance compared by using NS-2 and output verified by using
Network Animator.
87
I.T Dept., MVSREC CN/OS Lab
OS PROGRAMS:
PROGRAM 1:
A) Write a shell script to find whether the given number is palindrome or not
Program:
echo -n "Enter number : "
read n
while [ $n -gt 0 ]
do
sd=$(( $n % 10 )) # get Remainder
n=$(( $n / 10 )) # get next digit
# store previous number and current digit in reverse
rev=$( echo ${rev}${sd} )
done
88
I.T Dept., MVSREC CN/OS Lab
B) Write a shell script to find whether the given number is Armstrong or not
x=$c
sum=0
r=0
n=0
while [ $x -gt 0 ]
do
r=`expr $x % 10`
n=`expr $r \* $r \* $r`
sum=`expr $sum + $n`
x=`expr $x / 10`
done
if [ $sum -eq $c ]
then
echo "It is an Armstrong Number."
else
echo "It is not an Armstrong Number."
fi
Ouput:
89
I.T Dept., MVSREC CN/OS Lab
PROGRAM 2:
AIM: Write a program to implement FCFS Process Scheduling Algorithm
ALGORITHM
PROGRAM:
#include<stdio.h>
main()
{
int n,a[10],b[10],t[10],w[10],g[10],i,m;
float att=0,awt=0;
for(i=0;i<10;i++)
{
a[i]=0; b[i]=0; w[i]=0; g[i]=0;
}
printf("enter the number of process");
scanf("%d",&n);
printf("enter the burst times");
for(i=0;i<n;i++)
scanf("%d",&b[i]);
printf("\nenter the arrival times");
for(i=0;i<n;i++)
scanf("%d",&a[i]);
g[0]=0;
for(i=0;i<10;i++)
g[i+1]=g[i]+b[i];
for(i=0;i<n;i++)
{
w[i]=g[i]-a[i];
t[i]=g[i+1]-a[i];
awt=awt+w[i];
att=att+t[i];
}
awt =awt/n;
90
I.T Dept., MVSREC CN/OS Lab
att=att/n;
printf("\n\tprocess\twaiting time\tturn arround time\n");
for(i=0;i<n;i++)
{
printf("\tp%d\t\t%d\t\t%d\n",i,w[i],t[i]);
}
printf("the average waiting time is %f\n",awt);
printf("the average turnaround time is %f\n",att);
}
OUTPUT:
91
I.T Dept., MVSREC CN/OS Lab
PROGRAM 3:
ATM: Write a program to implement SJF(Premptive) Process Scheduling Alogrithm
ALGORITHM
1. Start the process
2. Declare the array size
3. Get the number of elements to be inserted
4. Select the process which have shortest burst will execute first
5. If two process have same burst length then FCFS scheduling algorithm used
6. Make the average waiting the length of next process
7. Start with the first process from it’s selection as above and let other process to be in queue
8. Calculate the total number of burst time
9. Display the values
10. Stop the process
PROGRAM:
#include<stdio.h>
int main()
{
int n,j,temp,temp1,temp2,pr[10],b[10],t[10],w[10],p[10],i;
float att=0,awt=0;
for(i=0;i<10;i++)
{
b[i]=0;w[i]=0;
}
for(i=0;i<n;i++)
{
scanf("%d",&b[i]);
p[i]=i;
}
for(i=0;i<n;i++)
{
for(j=i;j<n;j++)
{
if(b[i]>b[j])
{
92
I.T Dept., MVSREC CN/OS Lab
temp=b[i];
temp1=p[i];
b[i]=b[j];
p[i]=p[j];
b[j]=temp;
p[j]=temp1;
}
}
}
w[0]=0;
for(i=0;i<n;i++)
w[i+1]=w[i]+b[i];
for(i=0;i<n;i++)
{
t[i]=w[i]+b[i];
awt=awt+w[i];
att=att+t[i];
}
awt=awt/n;
att=att/n;
printf("\n\t process \t waiting time \t turn around time \n");
for(i=0;i<n;i++)
printf("\t p[%d] \t %d \t\t %d \n",p[i],w[i],t[i]);
printf("the average waitingtimeis %f\n",awt);
printf("the average turn around time is %f\n",att);
return 1;
}
OUTPUT:
93
I.T Dept., MVSREC CN/OS Lab
PROGRAM 4:
AIM: Write a program to implement ROUND ROBIN Process Scheduling Algorithm
ALGORITHM
1. Start the process
2. Declare the array size
3. Get the number of elements to be inserted
4. Get the value
5. Set the time sharing system with preemption
6. Define quantum is defined from 10 to 100ms
7. Declare the queue as a circular
8. Make the CPU scheduler goes around the ready queue allocating CPU to each process for the time
interval specified
9. Make the CPU scheduler picks the first process and sets time to interrupt after quantum expired
dispatches the process
10. If the process have burst less than the time quantum than the process release the CPU
11. If the process have bust greater then time quantum then time will go off and cause interrupt to OS
and the process put into the tail of ready queue and the schedule select next process
12. Display the results
13. Stop the process
PROGRAM:
#include<stdio.h>
int ttime,i,j,temp;
main()
{
int pname[10],btime[10],pname2[10],btime2[10];
int n,x,z;
printf("Enter the no. of process:");
scanf("%d",&n);
printf("Enter the process name and burst time for the process\n");
for(i=0;i<n;i++)
{
printf("Enter the process name:");
scanf("%d",&pname2[i]);
printf("Enter burst time for the process %d:",pname2[i]);
scanf("%d",&btime2[i]);
}
printf("PROCESS NAME \t\t BURST TIME\n");
for(i=0;i<n;i++)
printf("%d\t\t\t %d\n",pname2[i],btime2[i]);
z=1;
while(z==1)
94
I.T Dept., MVSREC CN/OS Lab
{
ttime=0;
for(i=0;i<n;i++)
{
pname[i]=pname2[i];
btime[i]=btime2[i];
}
while(j<n)
{
for(i=0;i<n;i++)
{
if(btime[i]>0)
{
if(btime[i]>=tslice)
95
I.T Dept., MVSREC CN/OS Lab
{
ttime+=tslice;
btime[i]=btime[i]-tslice;
printf("\n%d\t\t %d \t\t %d",pname[i],btime[i],ttime);
if(btime[i]==0)
j++;
}
else
{
ttime+=btime[i];
btime[i]=0;
printf("\n%d\t\t %d \t\t %d",pname[i],btime[i],ttime);
}
}
}
}
}
Output:
96
I.T Dept., MVSREC CN/OS Lab
PROGRAM 5:
AIM: Write a program to implement Priority Process Scheduling Algorithm
Program:
#include<stdio.h>
main()
{
int i,j,n,tat[10],wt[10],bt[10],pid[10],pr[10],t,twt=0,ttat=0;
float awt,atat;
printf("\n-----------PRIORITY SCHEDULING--------------\n");
printf("Enter the No of Process: ");
scanf("%d", &n);
for (i=0;i<n;i++)
{
pid[i]=i;
printf(“enter the burst time of pid %d”,i);
scanf("%d",&bt[i]);
printf("Enter the Priority of Pid %d : ",i);
scanf ("%d",&pr[i]);
}
// Sorting start
for (i=0;i pr[j] )
{
t = pr[i];
pr[i] = pr[j];
pr[j] = t;
t = bt[i];
bt[i] = bt[j];
bt[j] = t;
t = pid[i];
pid[i] = pid[j];
pid[j] = t;
}
}
// Sorting finished
tat[0] = bt[0];
wt[0] = 0;
for (i=1;i<n;i++)
{
wt[i]=wt[i-1]+bt[i-1];
tat[i] = wt[i] + bt[i];
}
printf("\n---------------------------------------------------------------\n");
printf("Pid\t Priority\tBurst time\t WaitingTime\tTurnArroundTime\n");
printf("\n--------------------------------------------------------------\n");
for(i=0;i<n;i++)
{
printf("\n%d\t\t%d\t%d\t\t%d\t\t%d",pid[i],pr[i],bt[i],wt[i],tat[i]);
}
for(i=0;i<n;i++)
{
ttat = ttat+tat[i];
twt = twt + wt[i];
97
I.T Dept., MVSREC CN/OS Lab
}
awt = (float)twt / n;
atat = (float)ttat / n;
printf("\n\nAvg.Waiting Time: %f\nAvg.Turn Around Time: %f\n",awt,atat);
}
Output:
98
I.T Dept., MVSREC CN/OS Lab
PROGRAM 6 :
Program:
#include<stdio.h>
main()
{
int n,i,j,b[20],sb[20],t[20],x,c[20][20];
printf("Enter no.of files:");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("Enter no. of blocks occupied by file%d",i+1);
scanf("%d",&b[i]);
printf("Enter the starting block of file%d",i+1);
scanf("%d",&sb[i]);
t[i]=sb[i];
for(j=0;j<b[i];j++)
c[i][j]=sb[i]++;
}
printf("Filename\tStart block\tlength\n");
for(i=0;i<n;i++)
printf("%d\t %d \t%d\n",i+1,t[i],b[i]);
printf("Enter file name:");
scanf("%d",&x);
printf("File name is:%d",x);
printf("length is:%d",b[x-1]);
printf("blocks occupied:");
for(i=0;i<b[x-1];i++)
printf("%4d",c[x-1][i]);
}
Output:
Enter no.of files: 2
Enter no. of blocks occupied by file
14
Enter the starting block of file
12
Enter no. of blocks occupied by file
2 10
Enter the starting block of file
25
Filename Start block length
124
2 5 10
Enter file name: rajesh File name is: 12803 lengths is: 0blocks occupied
99
I.T Dept., MVSREC CN/OS Lab
PROGRAM 7 :
#include<stdio.h>
#include<pthread.h>
#include<sys/types.h>
#include<unistd.h>
#include<stdlib.h>
#include<semaphore.h>
sem_t empty,full,mutex;
char buf[10];
void* thread_fun1(void* arg)
{
int i;
//printf("inside producer\n");
for(i=0;i<10;i++)
{
sem_wait(&empty);
sem_wait(&mutex);
buf[i]=i;
printf("item produced is %d\n",buf[i]);
sem_post(&mutex);
sem_post(&full);
sleep(1);
}
pthread_exit("producer\n");
}
void * thread_fun2(void* arg)
{
int j;
printf("inside consumer\n");
for(j=0;j<10;j++)10
{
sem_wait(&full);
sem_wait(&mutex);
// sleep(1);
j=buf[j];
printf("consumed item is:%d\n",buf[j]);
sem_post(&mutex);
sem_post(&empty);
sleep(5);
}
pthread_exit("consumer\n");
}
int main()
{
pthread_t pid1,pid2;
sem_init(&empty,0,10);
100
I.T Dept., MVSREC CN/OS Lab
sem_init(&full,0,0);
sem_init(&mutex,1,1);
void *status;
pthread_create(&pid1,NULL,thread_fun1,NULL);
pthread_create(&pid2,NULL,thread_fun2,NULL);
pthread_join(pid1,&status);
printf("the exited status of 1st is %s\n",(char*)status);
pthread_join(pid2,&status);
printf("the exited status %s\n",(char*)status);
return 0;
}
OUTPUT:
101
I.T Dept., MVSREC CN/OS Lab
PROGRAM 8:
AIM: Write a C program to implement Bankers algorithm for Dead Loack Avoidance
Program:
#include<stdio.h>
struct da
{
int max[10],a1[10],need[10],before[10],after[10];
}p[10];
main()
{
int i,j,k,l,r,n,tot[10],av[10],cn=0,cz=0,temp=0,c=0;
printf("\n ENTER THE NO. OF PROCESSES:");
scanf("%d",&n);
printf("\n ENTER THE NO. OF RESOURCES:");
scanf("%d",&r);
for(i=0;i<n;i++)
{
printf("PROCESS %d \n",i+1);
for(j=0;j<r;j++)
{
printf("MAXIMUM VALUE FOR RESOURCE %d:",j+1);
scanf("%d",&p[i].max[j]);
}
for(j=0;j<r;j++)
{
printf("ALLOCATED FROM RESOURCE %d:",j+1);
scanf("%d",&p[i].a1[j]);
p[i].need[j]=p[i].max[j]-p[i].a1[j];
}
}
for(i=0;i<r;i++)
{
printf("ENTER TOTAL VALUE OF RESOURCE %d:",i+1);
scanf("%d",&tot[i]);
}
for(i=0;i<r;i++)
{
for(j=0;j<n;j++)
temp=temp+p[j].a1[i];
av[i]=tot[i]-temp;
temp=0;
}
printf("\n\t RESOURCES ALLOCATED NEEDED TOTAL AVAIL");
for(i=0;i<n;i++)
{
printf("\n P%d \",i+1);
for(j=0;j<r;j++)
102
I.T Dept., MVSREC CN/OS Lab
printf("%d",p[i].max[j]);
printf("\t");
for(j=0;j<r;j++)
printf("%d",p[i].a1[j]);
printf("\t");
for(j=0;j<r;j++)
printf("%d",p[i].need[j]);
printf("\t");
for(j=0;j<r;j++)
{
if(i==0)
printf("%d",tot[j]);
}
printf(" ");
for(j=0;j<r;j++)
{
if(i==0)
printf("%d",av[j]);
}
}
printf("\n\n\t AVAIL BEFORE\T AVAIL AFTER ");
for(I=0;I<n;I++)
{
for(i=0;i<n;i++)
{
for(j=0;j<r;j++)
{
if(p[i].need[j] >av[j])
cn++;
if(p[i].max[j]==0)
cz++; }
if(cn==0 && cz!=r)
{
for(j=0;j<r;j++)
{
p[i].before[j]=av[j]-p[i].need[j];
p[i].after[j]=p[i].before[j]+p[i].max[j];
av[j]=p[i].after[j];
p[i].max[j]=0;
}
printf("\n P %d \t",i+1);
for(j=0;j<r;j++)
printf("%d",p[i].before[j]);
printf("\t");
for(j=0;j<r;j++)
printf("%d",p[i].after[j]);
cn=0;
cz=0;
c++;
break;
}
else
{
103
I.T Dept., MVSREC CN/OS Lab
cn=0;
cz=0;
}
}
}
if(c==n)
printf("\n THE ABOVE SEQUENCE IS A SAFE SEQUENCE");
else
printf("\n DEADLOCK OCCURED");
}
Output:
104
I.T Dept., MVSREC CN/OS Lab
PROGRAM 9:
ALGORITHM
1. Start the process
2. Declare the size with respect to page length
3. Check the need of replacement from the page to memory
4. Check the need of replacement from old page to new page in memory
5. Forma queue to hold all pages
6. Insert the page require memory into the queue
7. Check for bad replacement and page fault
8. Get the number of processes to be inserted
9. Display the values
10. Stop the process
PROGRAM:
#include<stdio.h>
int main()
{
int i,j,n,a[50],frame[10],no,k,avail,count=0;
printf("\n ENTER THE NUMBER OF PAGES:\n");
scanf("%d",&n);
printf("\n ENTER THE PAGE NUMBER :\n");
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
printf("\n ENTER THE NUMBER OF FRAMES :");
scanf("%d",&no);
for(i=0;i<no;i++)
frame[i]= -1;
j=0;
printf("\tref string\t page frames\n");
for(i=1;i<=n;i++)
{
printf("%d\t\t",a[i]);
avail=0;
for(k=0;k<no;k++)
if(frame[k]==a[i])
avail=1;
if (avail==0)
{
frame[j]=a[i];
j=(j+1)%no;
count++;
105
I.T Dept., MVSREC CN/OS Lab
for(k=0;k<no;k++)
printf("%d\t",frame[k]);
}
printf("\n");
}
printf("Page Fault Is %d",count);
return 0;
}
Output:
106
I.T Dept., MVSREC CN/OS Lab
PROGRAM 10:
ALGORITHM :
PROGRAM:
#include<stdio.h>
main()
{
int q[20],p[50],c=0,c1,d,f,i,j,k=0,n,r,t,b[20],c2[20];
printf("Enter no of pages:");
scanf("%d",&n);
printf("Enter the reference string:");
for(i=0;i<n;i++)
scanf("%d",&p[i]);
printf("Enter no of frames:");
scanf("%d",&f);
q[k]=p[k];
printf("\n\t%d\n",q[k]);
c++;
k++;
for(i=1;i<n;i++)
{
c1=0;
107
I.T Dept., MVSREC CN/OS Lab
for(j=0;j<f;j++)
{
if(p[i]!=q[j])
c1++;
}
if(c1==f)
{
c++;
if(k<f)
{
q[k]=p[i];
k++;
for(j=0;j<k;j++)
printf("\t%d",q[j]);
printf("\n");
}
else
{
for(r=0;r<f;r++)
{
c2[r]=0;
for(j=i-1;j<n;j--)
{
if(q[r]!=p[j])
c2[r]++;
else
break;
}
}
for(r=0;r<f;r++)
b[r]=c2[r];
for(r=0;r<f;r++)
{
for(j=r;j<f;j++)
{
if(b[r]<b[j])
{
t=b[r];
b[r]=b[j];
b[j]=t;
}
}
}
for(r=0;r<f;r++)
{
108
I.T Dept., MVSREC CN/OS Lab
if(c2[r]==b[0])
q[r]=p[i];
printf("\t%d",q[r]);
}
printf("\n");
}
}
}
printf("\nThe no of page faults is %d",c);
}
Output:
109
I.T Dept., MVSREC CN/OS Lab
111
I.T Dept., MVSREC CN/OS Lab
* It contains user program, user data,stack,PCB.
46. Define PCB?
* Process control block is used to control process states.
47. Define process attributes?
* Process has a series of characteristics which are called as a process attributes.
48. List process states?
* Ready, Execution, Suspend, Stopped, Zombie.
49. Define Zombie process?
* The child process terminates while before the parent dies.
50. Define Orphan process?
* The parent process wants to terminate before the child process.
51. List process management functions?
* fork,vfork,exit,wait,waitpid,exec family ,system.
52. What is vfork?
* It is a virtual fork.
53. Define Signal?
* Signal is a software interrupt.
54. Define Reliable signal?
* Signal is generated by process when event occurs that causes the signal occurs.
55. Define Unreliable signal?
* Signals that cannot be identified.
56. What is IPC?
* Inter process communication describes different ways of msg passing b/w different processes that
are running on some o/s.
57. List methods of IPC?
* Pipes, FIFO’s, Msgqueues, Semaphores,Shared m/y.
58. List types of pipes?
* Unidirectional & Bidirectional pipes.
59. What is Unidirectional pipe?
* Single directional flow of data.
60. What is Bidirectional pipe?
* Bi directional flow of data.
61. Define FIFO?
*FIFO/Named pipe is a permanent fixture.
62. Define Message Queue?
* It describes storing of data in a orbitary order.
63. Define Semaphore?
* Semaphore is a synchronization primitive.
64. Define Shared Memory? * It provides a way around this by letting two
or more processes shared a memory segment.
65. Define Socket?
* It is a local network of a people with outside world process.
66. List Linux API’s of messages?
*msgget, msgsnd, msgrcv, msgctl.
67. List Linux API’s of semaphores?
* semget,semop,semctl
68. List Linux API’s of shared memory?
* shmget,shmat,shmdt,shmctl.
69. Define Thread?
* Multiple strands of execution in a single program .
70. Define light weight process?
* It can be viewed as a mapping b/w user threads & kernel threads.
71. List POSIX threads API’s?
112
I.T Dept., MVSREC CN/OS Lab
* Creating threads,Thread semaphores,Thread mutexes,Thread attributes,cancelling a thread.
72. Define Mutex?
* Which act as an mutual exclusion device to protect sections of code.
73. List Thread attributes?
* detached state,sched policy,sched param,
inherit sched,scope,stack size.
74. List Socket s/m call for connection oriented protocol?
* socket, bind ,listen, accept, connect ,read ,write.
75. List Socket s/m call for connection less protocol?
* socket,bind,sendto,recvfrom.
113
I.T Dept., MVSREC CN/OS Lab
CN VIVA Questions
114
I.T Dept., MVSREC CN/OS Lab
else { fprintf(stderr, "Socket created!\n"); }
23. Output of the program
simpleSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_TCP);
if (simpleSocket == -1) {
fprintf(stderr, "Could not create a socket!\n");
exit(1);}
else { fprintf(stderr, "Socket created!\n"); }
24. Output of the program
simpleSocket = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP);
if (simpleSocket == -1) {
fprintf(stderr, "Could not create a socket!\n");
exit(1);}
else { fprintf(stderr, "Socket created!\n"); }
25. Which Protocol accept by default Socket = socket(AF_INET, SOCK_STREAM, 0);
26. Which Protocol accept by default Socket = socket(AF_INET, SOCK_DGRAM, 0);
27. What the socket written on creation as output ?
28. What is socket file descriptor ?
29. Arguments for Bind() ?
30. What is the use of Bind() ?
31. simplePort = atoi(argv[1]); Means ?
32. What are the structure variables inAddress Structure?
33. What is the use of use INADDR_ANY ?
34. What is the use of hton() ?
35. What is the use of ntoh()?
36. What is network byte ordering ?
37. No of octets accepted by htonl() ?
38. No of octets accepted by htons() ?
39. If socket value is -1 what is the output
115
I.T Dept., MVSREC CN/OS Lab
returnStatus = bind(simpleSocket, (structsockaddr *)&simpleServer, sizeof(simpleServer));
if (returnStatus == 0)
{ fprintf(stderr, "Bind completed!\n"); }
else { fprintf(stderr, "Could not bind to address!\n");
close(simpleSocket);
exit(1); }
41. What will be the output of Bind() on successful bind of address ?
42. What is the use of listen () ?
43. Arguments accepted by listen() ?
44. What is the need of backlog value in Listen() ?
45. The maximum value of backlog in BSD based systems ?
47. If Socket was successfully created& backlog =5 what will be the output
117
I.T Dept., MVSREC CN/OS Lab
118