Академический Документы
Профессиональный Документы
Культура Документы
COMPUTER NETWORKS
Exercise 1:
Aim:
To write a program for implementing the Data Link Layer framing methods such as character,
character stuffing and bit stuffing
DESCRIPTION
Data Framing:
The term “frame” refers to a small block of data used in a specific network. The data link layer
groups raw data bits to/from the physical layer into discrete frames with error detection/correction
code bits added. Framing methods:
Character count.
Starting and ending characters, with character stuffing.
Starting and ending flags with bit stuffing.
Physical layer coding violations.
Error Detection/Correction:
Error Detection:
Include enough redundant information in each frame to allow the receiver to
deduce that an error has occurred, but not which error and to request a
retransmission.
Uses error-detecting codes.
Error Correction:
Include redundant information in the transmitted frame to enable the receiver
not only to deduce that an error has occurred but also correct the error.
Uses error-correcting codes.
Protocols to control the rate the sender transmits frames at a rate acceptable to the receiver, and the
ability to retransmit lost or damaged frames. This insures that slow receivers are not swamped by
fast senders and further aids error detection/correction.
Several flow control protocols exist, but all essentially require a form of feedback to
make the sender aware of whether the receiver can keep up.
Stop-and-wait Protocols:
A positive acknowledgment frame is sent by the receiver to indicate
that the frame has been received and to indicate being ready for the
next frame.
Positive Acknowledgment with Retransmission (PAR); uses timeouts
Sliding Window Protocols:
Data frames and acknowledgement frames are mixed in both directions.
Frames sent contain sequence numbers
Timeouts used to initiate retransmission of lost frames.
Each frame starts with the ASCII character sequence DLE (Data Link Escape) and STX (Start
of TeXt) and ends with DLE ETX (End of TeXt)
When binary data is transmitted where (DLE STX or DLE ETX) can occur in data, character
stuffing is used (additional DLE is inserted in the data).
Limited to 8-bit characters and ASCII.
PROCEDURES:
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<process.h>
void main()
{
int i=0,j=0,n,pos;
char a[20],b[50],ch;
clrscr();
printf("enter string\n");
scanf("%s",&a);
n=strlen(a);
printf("enter position\n");
scanf("%d",&pos);
if(pos>n)
{
printf("invalid position, Enter again :");
scanf("%d",&pos);
}
printf("enter the character\n");
ch=getche();
b[0]='d';
b[1]='l';
b[2]='e';
b[3]='s';
b[4]='t';
b[5]='x';
j=6;
while(i<n)
{
if(i==pos-1)
{
b[j]='d';
b[j+1]='l';
b[j+2]='e';
b[j+3]=ch;
b[j+4]='d';
b[j+5]='l';
b[j+6]='e';
j=j+7;
}
if(a[i]=='d' && a[i+1]=='l' && a[i+2]=='e')
{
b[j]='d';
b[j+1]='l';
b[j+2]='e';
j=j+3;
}
b[j]=a[i];
i++;
j++;
}
b[j]='d';
b[j+1]='l';
b[j+2]='e';
b[j+3]='e';
b[j+4]='t';
b[j+5]='x';
b[j+6]='\0';
printf("\nframe after stuffing:\n");
printf("%s",b);
getch();
}
INPUT:
enter string:
asdlefgh
enter position: 8
invalid position,enter again: 3
enter the character: k
OUTPUT:
frame after stuffing:
dlestx as dle k dledledlefghdleetx
#include<stdio.h>
#include<conio.h>
#include<string.h>
void main()
{
int a[20],b[30],i,j,k,count,n;
clrscr();
printf("Enter frame length:");
scanf("%d",&n);
printf("Enter input frame (0's & 1's only):");
for(i=0;i<n;i++)
scanf("%d",&a[i]);
i =0; count=1; j=0;
while(i<n)
{
if(a[i]==1)
{
b[j]=a[i];
for(k=i+1;a[k]==1 && k<n && count<5;k++)
{
j++;
b[j]=a[k];
count++;
if(count==5)
{
j++;
b[j]=0;
}
i=k;
}}
else
{
b[j]=a[i];
}
i++;
j++;
}
printf("After stuffing the frame is:");
for(i=0;i<j;i++)
printf("%d",b[i]);
getch();
}
INPUT:
Enter frame length: 10
Enter input frame (0's & 1's only):
1010111111
OUTPUT:
After stuffing the frame is:
10101111101
CRC POLYNOMIALS
Exercise-2
DESCRIPTION
Data Link Layer: Error Detection/Correction
. Simplest error detection : Parity bits and checksum (sum of 1’s in Data).
. Error-detecting and -correcting codes:
m data bits + r redundant bits added.
n =m + r transmitted in frame.
Only 2m code words out of possible 2m+r words are legal.
The Hamming distance --minimum number of positions any two legal code words
differ-- of a code defines its error detection/correction ability.
To detect d errors code Hamming distance = d + 1
To correct d errors code Hamming distance = 2d + 1
Some codes are more suitable to correct burst errors rather than isolated errors.
Polynomial codes: Cyclic Redundancy Check (CRC) Codes, are characterized by a
generating polynomial G(X)
1. For degree of generating polynomial G(x) = r , append r zero bits to low-order of frame. The
frame now has m+r bits.
2. Divide the bit string corresponding to G(X) into the bit string xrM(x) mod(2)
3. Subtract the remainder R(x) from the bit string xrM(x) mod(2)
PROCEDURES:
#include<stdio.h>
#include<conio.h>
int gen[4],genl,frl,rem[4];
void main()
{
int i,j,fr[8],dupfr[11],recfr[11],tlen,flag;
clrscr();
frl=8; genl=4;
printf("enter frame:");
for(i=0;i<frl;i++)
{
scanf("%d",&fr[i]);
dupfr[i]=fr[i];
}
printf("enter generator:");
for(i=0;i<genl;i++)
scanf("%d",&gen[i]);
tlen=frl+genl-1;
for(i=frl;i<tlen;i++)
{
dupfr[i]=0;
}
remainder(dupfr);
for(i=0;i<frl;i++)
{
recfr[i]=fr[i];
}
for(i=frl,j=1;j<genl;i++,j++)
{
recfr[i]=rem[j];
}
remainder(recfr);
flag=0;
for(i=0;i<4;i++)
{
if(rem[i]!=0)
flag++;
}
if(flag==0)
{
printf("frame received correctly");
}
else
{
printf("the received frame is wrong");
}
getch();
}
remainder(int fr[])
{
int k,k1,i,j;
for(k=0;k<frl;k++)
{
if(fr[k]==1)
{
k1=k;
for(i=0,j=k;i<genl;i++,j++)
{
rem[i]=fr[j]^gen[i];
}
for(i=0;i<genl;i++)
{
fr[k1]=rem[i];
k1++;
}
}
}
}
INPUT:
Enter frame :
11111111
enter generator :
1101
Hamming code
Exercise 3
Implement one bit error correction in the received frame using Hamming code.
Description:
Hamming code is a popular error detection and error correction method in data communication.
Hamming code can only detect 2 bit error and correct a single bit error which means it is unable to
correct burst errors if may occur while transmission of data.
Hamming code uses redundant bits (extra bits) which are calculated according to the below formula:-
2 ≥ m+r+1
r
Where r is the number of redundant bits required and m is the number of data bits.
These redundant bits are then added to the original data for the calculation of error at the receiver's end.
At the receiver's end with the help of even parity (generally) the erroneous bit position is identified and
since data is in binary we take complement of the erroneous bit position to correct received data.
Implement one bit error correction in the received frame using Hamming code.
scanf("%d",&data[2]);
scanf("%d",&data[4]);
c1=dataatrec[6]^dataatrec[4]^dataatrec[2]^dataatrec[0];
c2=dataatrec[5]^dataatrec[4]^dataatrec[1]^dataatrec[0];
c3=dataatrec[3]^dataatrec[2]^dataatrec[1]^dataatrec[0];
c=c3*4+c2*2+c1 ;
if(c==0) {
printf("\nNo error while transmission of data\n");
}
else {
printf("\nError on position %d",c);
for (i=0;i<7;i++) {
printf("%d",dataatrec[i]);
}
}
OUTPUT:
Enter 4 bits of data one by one
1
0
1
0
Encoded data is
1010010
Enter received data bits one by one
1
0
1
0
0
1
0
No error while transmission of data
Exercise 4
DESCRIPTION
Routing algorithms are a part of the network layer software whose responsibility is to decide what
destination output line should be selected for successful journey completion of the packet from the
source machine to destination machine. The network layer of ISO-OSI reference model is responsible
for getting packets from the source to the destination. It uses routing algorithms to effectively use all
communication lines and routers present in the communication subnet and decide which lines to use
for forwarding incoming packets.
Most computer networks in operation today use dynamic routing algorithms rather than static
routing algorithms. One of the widely used dynamic algorithms is Distance Vector routing, which is
also known as Bellman Ford algorithm. A table maintained by a router is called a vector. Vectors
contain information on how to get to the destination using the best possible path to get to it. It also
contains an entry for each router in the subnet. Each of the routing tables is updated continuously.
This can be done by exchanging information with the neighboring routers. For measuring the optimal
distance between each node, metrics are used, similar to ones described above in the classification
section of the article. The optimal path is followed till the packet reaches the destination machine.
Distance vector algorithms use the Bellman-Ford algorithm. This approach assigns a number, the
cost, to each of the links between each node in the network. Nodes will send information from point
A to point B via the path that results in the lowest total cost (i.e. the sum of the costs of the links
between the nodes used). The algorithm operates in a very simple manner. When a node first starts, it
only knows of its immediate neighbours, and the direct cost involved in reaching them. (This
information, the list of destinations, the total cost to each, and the next hop to send data to get there,
makes up the routing table, or distance table.) Each node, on a regular basis, sends to each neighbour
its own current idea of the total cost to get to all the destinations it knows of. The neighbouring
node(s) examine this information, and compare it to what they already 'know'; anything which
represents an improvement on what they already have, they insert in their own routing table(s). Over
time, all the nodes in the network will discover the best next hop for all destinations, and the best
total cost.
When one of the nodes involved goes down, those nodes which used it as their next hop for
certain destinations discard those entries, and create new routing-table information. They then pass
this information to all adjacent nodes, which then repeat the process. Eventually all the nodes in the
network receive the updated information, and will then discover new paths to all the destinations
which they can still "reach".
Implementation Using C
#include<ctype.h>
#include<stdio.h>
#include<conio.h>
#include<string.h>
int dest,ja,ji,jk,j,jh,min,delay;
char dnode,line;
struct newj
{
int delay;
char line;
}s[12];
int a[12]={0,12,25,40,14,23,18,17,21,9,24,29};
int i[12]={24,36,18,27,7,20,31,20,0,11,22,33};
int h[12]={20,31,19,8,30,19,6,0,14,7,22,9};
int k[12]={21,28,36,24,22,40,31,19,22,10,0,9};
main()
{
ja=8;
ji=10;
jh=12;
jk=6;
clrscr();
printf("\n The source node is j");
printf("\n The adjacent nodes from j are a,i,h,k");
printf("\n Enter the destination node");
scanf("%c",&dnode);
dest=toupper(dnode)-'A';
for(j=0;j<12;j++)
{
min=a[j]+ja;
line='a';
if(min>i[j]+ji)
{
line='i';
min=i[j]+ji;
}
if(min>h[j]+jh)
{
line='h';
min=h[j]+jh;
}
if(min>k[j]+jk)
{
line='k';
min=k[j]+jk;
}
s[j].delay=min;
s[j].line=line;
}
printf("The routing table is ");
printf("\n Dest \t Distance \t via node");
for(j=0;j<12;j++)
if(j==9)
printf("\n j \t 0 \t \t j");
else
printf("\n %c \t %d \t \t %c", j+'a', s[j].delay”);
s[j].line);
if(dest==9)
printf("\n Delay from source j to destination j is 0 via j");
else
printf("\n Delay from source j to %c is %d via %c",
dnode,s[dest]. delay, s[dest]. line);
getch(); }
OUTPUT
Exercise 5:
DESCRIPTION
Suppose we have a group of islands that we wish to link with bridges so that it is possible to travel
from one island to any other in the group. Further suppose that (as usual) our government wishes to
spend the absolute minimum amount on this project (because other factors like the cost of using,
maintaining, etc, these bridges will probably be the responsibility of some future government.
The engineers are able to produce a cost for a bridge linking each possible pair of islands. The set of
bridges which will enable one to travel from any island to any other at minimum capital cost to the
government is the minimum spanning tree.
Graphs
G = (V,E)
E = { (v ,v ) } i j
Paths
Cycles
A graph contains no cycles if there is no path of non-zero length through the graph, p = <v ,v ,...,v > 0 1 k
such that v = v .
0 k
Spanning Trees
A spanning tree of a graph, G, is a set of |V|-1 edges that connect all vertices of the graph.
In general, it is possible to construct multiple spanning trees for a graph, G. If a cost, c , is associated
ij
with each edge, e = (v ,v ), then the minimum spanning tree is the set of edges, E , forming a
ij i j span
Forexample:
We want a subset, T, of edges, E, such that the graph remains connected if only the edges in T are
used, and the sum of the lengths of edges in T is as small as possible.
Krushkal’s Algorithm
This algorithm creates a forest of trees. Initially the forest consists of n single node trees (and no
edges). At each step, we add one (the cheapest one) edge so that it joins two trees together. If it were
to form a cycle, it would simply link two nodes that were already part of a single connected tree, so
that this edge would not be needed.
Every step will have joined two trees in the forest together, so that at the end, there will only be one
tree in T.
Prim's Algorithm
Step 1
Pick any vertex as a starting vertex. (Call it S). Mark it with any given colour, say red.
Step 2
Find the nearest neighbour of S (call it P1). Mark both P1 and the edge SP1 red. cheapest unmarked
(uncoloured) edge in the graph that doesn't close a coloured circuit. Mark this edge with same colour
of Step 1.
Step 3
Find the nearest uncoloured neighbour to the red subgraph (i.e., the closest vertex to any red vertex). Mark it
and the edge connecting the vertex to the red subgraph in red.
Step 4
Repeat Step 2 until all vertices are marked red. The red subgraph is a minimum spanning tree.
Implementation Using C
#include<stdio.h>
int p,q,u,v,n;
int min=99,mincost=0;
int t[50][2],i,j;
int parent[50],edge[50][50];
main()
{
clrscr();
printf("\n Enter the number of nodes");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("%c\t",65+i);
parent[i]=-1;
}
printf("\n");
for(i=0;i<n;i++)
{
printf("%c",65+i);
for(j=0;j<n;j++)
scanf("%d",&edge[i][j]);
}
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
if(edge[i][j]!=99)
if(min>edge[i][j])
{
min=edge[i][j];
u=i;
v=j;
}
p=find(u);
q=find(v);
if(p!=q)
{
t[i][0]=u;
t[i][1]=v;
mincost=mincost+edge[u][v];
sunion(p,q);
}
else
{
t[i][0]=-1;
t[i][1]=-1;
}
min=99;
}
printf("Minimum cost is %d\n Minimum spanning tree is\n" ,mincost);
,mincost);
for(i=0;i<n;i++)
if(t[i][0]!=-1 && t[i][1]!=-1)
{
printf("%c %c %d", 65+t[i][0], 65+t[i][1],
edge[t[i][0]][t[i][1]]);
printf("\n");
}
getch();
}
void sunion(int l,int m)
{
parent[l]=m;
}
Int find(int l)
{
if(parent[l]>0)
l=parent[l];
return l;
}
INPUT:
OUTPUT:
Minimum cost is 7
Minimum spanning tree is
AB1
CA1
DB1
EA2
FD2
DESCRIPTION
If we are creating a connection between client and server using TCP then it has few functionalities like,
TCP is suited for applications that require high reliability, and transmission time is relatively less
critical. It is used by other protocols like HTTP, HTTPs, FTP, SMTP, Telnet. TCP rearranges data
packets in the order specified. There is absolute guarantee that the data transferred remains intact and
arrives in the same order in which it was sent. TCP does Flow Control and requires three packets to set
up a socket connection, before any user data can be sent. TCP handles reliability and congestion
control. It also does error checking and error recovery. Erroneous packets are retransmitted from the
source to the destination.
The entire process can be broken down into following steps:
TCP Server:
1. using create(), Create TCP socket.
2. using bind(), Bind the socket to server address.
3. using listen(), put the server socket in a passive mode, where it waits for the client to approach
the server to make a connection
4. using accept(), At this point, connection is established between client and server, and they are
ready to transfer data.
5. Go back to Step 3.
TCP Client:
1. Create TCP socket.
2. connect newly created client socket to server.
PROGRAM:
TCP SERVER:
#include <stdio.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#define MAX 80
#define PORT 8080
#define SA struct sockaddr
// Driver function
int main()
{
int sockfd, connfd, len;
struct sockaddr_inservaddr, cli;
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(PORT);
TCP CLIENT:
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#define MAX 80
#define PORT 8080
#define SA struct sockaddr
void func(int sockfd)
{
char buff[MAX];
int n;
for (;;) {
bzero(buff, sizeof(buff));
printf("Enter the string : ");
n = 0;
while ((buff[n++] = getchar()) != '\n')
;
write(sockfd, buff, sizeof(buff));
bzero(buff, sizeof(buff));
read(sockfd, buff, sizeof(buff));
printf("From Server : %s", buff);
if ((strncmp(buff, "exit", 4)) == 0) {
printf("Client Exit...\n");
break;
}
}
}
int main()
{
int sockfd, connfd;
struct sockaddr_inservaddr, cli;
Compilation –
Server side:
gccserver.c -o server
./server
Client side:
gccclient.c -o client
./client
OUTPUT –
Server side:
Socket successfully created..
Socket successfully binded..
Server listening..
server acccept the client...
From client: hi
To client : hello
From client: exit
To client : exit
Server Exit...
Client side:
Socket successfully created..
connected to the server..
Enter the string : hi
From Server : hello
Enter the string : exit
From Server : exit
Client Exit...
OPERATING SYSTEMS
// Driver code
int main()
{
//process id's
int processes[] = { 1, 2, 3};
int n = sizeof processes / sizeofprocesses[0];
findavgTime(processes, n, burst_time);
return 0;
}
Output:
//flushall();
scanf("%s%d%d",pn[i],&at[i],&et[i]);
}
for(i=0; i<n; i++)
for(j=0; j<n; j++)
{
if(et[i]<et[j])
{
temp=at[i];
at[i]=at[j];
at[j]=temp;
temp=et[i];
et[i]=et[j];
et[j]=temp;
strcpy(t,pn[i]);
strcpy(pn[i],pn[j]);
strcpy(pn[j],t);
}
}
for(i=0; i<n; i++)
{
if(i==0)
st[i]=at[i];
else
st[i]=ft[i-1];
wt[i]=st[i]-at[i];
ft[i]=st[i]+et[i];
ta[i]=ft[i]-at[i];
totwt+=wt[i];
totta+=ta[i];
}
awt=(float)totwt/n;
ata=(float)totta/n;
printf("\nPname\tarrivaltime\texecutiontime\twaitingtime\ttatime");
for(i=0; i<n; i++)
printf("\n%s\t%5d\t\t%5d\t\t%5d\t\t%5d",pn[i],at[i],et[i],wt[i],ta[i]);
printf("\nAverage waiting time is:%f",awt);
printf("\nAverageturnaroundtime is:%f",ata);
getch();
}
Output:
Enter the number of process:3
Enter process name, arrival time& execution time:2 5 7
Enter process name, arrival time& execution time:3 6 14
Enter process name, arrival time& execution time:4 7 12
Pnamearrivaltimeexecutiontimewaitingtimetatime
2 5 7 0 7
4 7 12 5 17
3 6 14 18 32
Average waiting time is:7.666667
Average turnaround time is:18.666666
Priority Scheduling:
In priority scheduling algorithm each process has a priority associated with it and as each process hits
the queue, it is stored in based on its priority so that process with higher priority are dealt with first.
It should be noted that equal priority processes are scheduled in FCFS order.
To prevent high priority processes from running indefinitely the scheduler may decrease the priority of
the currently running process at each clock tick (i.e., at each clock interrupt). If this action causes its
priority to drop below that of the next highest process, a process switch occurs. Alternatively, each
process may be assigned a maximum time quantum that it is allowed to run. When this quantum is used
up, the next highest priority process is given a chance to run.
Program:
#include<stdio.h>
int main()
{
int bt[20],p[20],wt[20],tat[20],pr[20],i,j,n,total=0,pos,temp,avg_wt,avg_tat;
printf("Enter Total Number of Process:");
scanf("%d",&n);
//sorting burst time, priority and process number in ascending order using selection sort
for(i=0;i<n;i++)
{
pos=i;
for(j=i+1;j<n;j++)
{
if(pr[j]<pr[pos])
pos=j;
}
temp=pr[i];
pr[i]=pr[pos];
pr[pos]=temp;
temp=bt[i];
bt[i]=bt[pos];
bt[pos]=temp;
temp=p[i];
p[i]=p[pos];
p[pos]=temp;
}
total+=wt[i];
}
return 0;
}
Output:
P[1]
Burst Time:6
Priority:3
P[2]
Burst Time:2
Priority:2
P[3]
Burst Time:14
Priority:1
P[4]
Burst Time:6
Priority:4
The banker’s algorithm is a resource allocation and deadlock avoidance algorithm that tests for safety
by simulating the allocation for predetermined maximum possible amounts of all resources, then makes
an “s-state” check to test for possible activities, before deciding whether allocation should be allowed
to continue.
Program:
// Banker's Algorithm
#include <stdio.h>
int main()
{
// P0, P1, P2, P3, P4 are the Process names here
int n, m, i, j, k;
n = 5; // Number of processes
m = 3; // Number of resources
int alloc[5][3] = { { 0, 1, 0 }, // P0 // Allocation Matrix
{ 2, 0, 0 }, // P1
{ 3, 0, 2 }, // P2
{ 2, 1, 1 }, // P3
{ 0, 0, 2 } }; // P4
int flag = 0;
for (j = 0; j < m; j++) {
if (need[i][j] > avail[j]){
flag = 1;
break;
}
}
if (flag == 0) {
ans[ind++] = i;
for (y = 0; y < m; y++)
avail[y] += alloc[i][y];
f[i] = 1;
}
}
}
}
return (0);
Output:
Least Recently Used (LRU) page replacement algorithm works on the concept that the pages that are
heavily used in previous instructions are likely to be used heavily in next instructions. And the page
that are used very less are likely to be used less in future. Whenever a page fault occurs, the page that is
least recently used is removed from the memory frames. Page fault occurs when a referenced page in
not found in the memory frames.
Program:
#include<stdio.h>
return pos;
}
int main()
{
int no_of_frames, no_of_pages, frames[10], pages[30], counter = 0, time[10], flag1, flag2, i,
j, pos, faults = 0;
printf("Enter number of frames: ");
scanf("%d", &no_of_frames);
if(flag1 == 0){
for(j = 0; j <no_of_frames; ++j){
if(frames[j] == -1){
counter++;
faults++;
frames[j] = pages[i];
time[j] = counter;
flag2 = 1;
break;
}
}
}
if(flag2 == 0){
pos = findLRU(time, no_of_frames);
counter++;
faults++;
frames[pos] = pages[i];
time[pos] = counter;
}
printf("\n");
return 0;
}
Output:
Enter number of frames: 3
Enter number of pages: 6
Enter reference string: 5 7 5 6 7 3
5 -1 -1
5 7 -1
5 7 -1
576
576
376
Total Page Faults = 4
Exercise 10:
Files are normally stored on the disks. So, the main problem is how to allocate space to those files. So
that disk space is utilized effectively and files can be accessed quickly. Three major strategies of
allocating disc space are in wide use. Sequential, indexed and linked.
In this allocation strategy, each file occupies a set of contiguously blocks on the disk. This strategy is
best suited. For sequential files, the file allocation table consists of a single entry for each file. It shows
the filenames, starting block of the file and size of the file. The main problem with this strategy is, it is
difficult to find the contiguous free blocks in the disk and some free blocks could happen between two
files.
Program:
#include <stdio.h>
#include<conio.h>
void main()
{
int f[50], i, st, len, j, c, k, count = 0;
clrscr();
for(i=0;i<50;i++)
f[i]=0;
printf("Files Allocated are : \n");
x: count=0;
printf(“Enter starting block and length of files: ”);
scanf("%d%d", &st,&len);
for(k=st;k<(st+len);k++)
if(f[k]==0)
count++;
if(len==count)
{
for(j=st;j<(st+len);j++)
if(f[j]==0)
{
f[j]=1;
printf("%d\t%d\n",j,f[j]);
}
if(j!=(st+len-1))
printf(” The file is allocated to disk\n");
}
else
printf(” The file is not allocated \n");
printf("Do you want to enter more file(Yes - 1/No - 0)");
scanf("%d", &c);
if(c==1)
goto x;
else
exit();
getch();
}
Output:
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.
Advantages:
This supports direct access to the blocks occupied by the file and therefore provides fast access
to the file blocks.
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.
Program:
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
void main()
{
int f[50], index[50],i, n, st, len, j, c, k, ind,count=0;
clrscr();
for(i=0;i<50;i++)
f[i]=0;
x:printf("Enter the index block: ");
scanf("%d",&ind);
if(f[ind]!=1)
{
printf("Enter no of blocks needed and no of files for the index %d on the disk : \n", ind);
scanf("%d",&n);
}
else
{
printf("%d index is already allocated \n",ind);
goto x;
}
y: count=0;
for(i=0;i<n;i++)
{
scanf("%d", &index[i]);
if(f[index[i]]==0)
count++;
}
if(count==n)
{
for(j=0;j<n;j++)
f[index[j]]=1;
printf("Allocated\n");
printf("File Indexed\n");
for(k=0;k<n;k++)
printf("%d-------->%d : %d\n",ind,index[k],f[index[k]]);
}
else
{
printf("File in the index is already allocated \n");
printf("Enter another file indexed");
goto y;
}
printf("Do you want to enter more file(Yes - 1/No - 0)");
scanf("%d", &c);
if(c==1)
goto x;
else
exit(0);
getch();
}
Output:
6-------->7 : 1
6-------->8 : 1
Do you want to enter more file(Yes - 1/No - 0)0
Exercise 11:
In SCAN disk scheduling algorithm, head starts from one end of the disk and moves towards the other
end, servicing requests in between one by one and reach the other end. Then the direction of the head is
reversed and the process continues as head continuously scan back and forth to access the disk. So, this
algorithm works as an elevator and hence also known as the elevator algorithm. As a result, the
requests at the midrange are serviced more and those arriving behind the disk arm will have to wait.
Program:
#include<conio.h>
#include<stdio.h>
int main()
{
int i,j,sum=0,n;
int d[20];
int disk; //loc of head
int temp,max;
int dloc; //loc of disk in array
clrscr();
printf("enter number of location\t");
scanf("%d",&n);
printf("enter position of head\t");
scanf("%d",&disk);
printf("enter elements of disk queue\n");
for(i=0;i<n;i++)
{
scanf("%d",&d[i]);
}
d[n]=disk;
n=n+1;
for(i=0;i<n;i++) // sorting disk locations
{
for(j=i;j<n;j++)
{
if(d[i]>d[j])
{
temp=d[i];
d[i]=d[j];
d[j]=temp;
}
}
}
max=d[n];
for(i=0;i<n;i++) // to find loc of disc in array
{
if(disk==d[i]) { dloc=i; break; }
}
for(i=dloc;i>=0;i--)
{
printf("%d -->",d[i]);
}
printf("0 -->");
for(i=dloc+1;i<n;i++)
{
printf("%d-->",d[i]);
}
sum=disk+max;
printf("\nmovement of total cylinders %d",sum);
getch();
return 0;
}
Output:
This algorithm helps to determine which job is nearest to the current head
position with minimum seek time, and then services that job next.
In the SSTF algorithm, the jobs having the shortest seek time are executed first.
Therefore, the seek time of each job is pre-calculated in the job queue and every
job is scheduled according to its seek time.
This enables the job nearest to the disk arm to get executed first. It also has a
better average response time and throughput as compared to the FCFS
scheduling algorithm.
Program:
#include<stdio.h>
#include<conio.h>
#include<math.h>
void main()
{
int queue[100],t[100],head,seek=0,n,i,j,temp;
float avg;
//clrscr();
printf("*** SSTF Disk Scheduling Algorithm ***\n");
printf("Enter the size of Queue\t");
scanf("%d",&n);
printf("Enter the Queue\t");
for(i=0;i<n;i++)
{
scanf("%d",&queue[i]);
}
printf("Enter the initial head position\t");
scanf("%d",&head);
for(i=1;i<n;i++)
t[i]=abs(head-queue[i]);
for(i=0;i<n;i++)
{
for(j=i+1;j<n;j++)
{
SVECW(Autonomous)/Dept. of CSE Page 52
Computer Networks and Operating Systems Lab Manual
if(t[i]>t[j])
{
temp=t[i];
t[i]=t[j];
t[j]=temp;
temp=queue[i];
queue[i]=queue[j];
queue[j]=temp;
}
}
}
for(i=1;i<n-1;i++)
{
seek=seek+abs(head-queue[i]);
head=queue[i];
}
printf("\nTotal Seek Time is%d\t",seek);
avg=seek/(float)n;
printf("\nAverage Seek Time is %f\t",avg);
getch();
}
Output: