17103057 CSX - 354
Dr. B R AMBEDKAR NATIONAL INSTITUTE OF
TECHNOLOGY JALANDHAR
LAB FILE OF
NETWORK PROGRAMMING
SESSION 2020-2021
Submitted To: Submitted By:
Dr. Prince Rakesh Pandey
CSE Dept. CSE 3rd Year
17103057
G-3
1|Page
17103057 CSX - 354
INDEX
S.no Date Practical Page Remarks
no
1 17/01/2020 AIM-Write down the installation steps for ns3 3-5
simulator across Ubuntu sand demonstrate the
installation steps using suitable snapshots.
2 24/01/2020 AIM : Learn the configuration of netanim with ns-3 6-8
simulator.
3 31/01/2020 AIM : Demonstrate the client server interaction 9-11
using two nodes , communicating through UDP in
ns-3 simulator.
4 31/01/2020 AIM : Using the ns-3 simulator animate the desired 12-15
network topology for UDP communication.
5 6/02/2020 AIM : Using the built-in library examples, illustrate 16-18
the client interaction using a server and router
enabling UDP data transfer.
6 6/02/2020 AIM: Write down a C program demonstrating the 19-20
use of Process IDs at Ubuntu terminal for multiple
process applications.
7 20/02/2020 AIM : Demonstrate the implementation of Pipes for 21-24
IPC in between client server processes using C
language programs.
8 20/02/2020 AIM : Demonstrate the implementation of FIFOs for 24-26
IPC in between client server processes using C
language programs.
9 27/02/2020 AIM : Demonstrate the implementation of message 27-28
queues for IPC in between client server processes
using C language programs.
10 27/02/2020 AIM : Write two programs one each for client and 29-35
server to create an integer variable using shared
memory concept and increment the variable
simultaneously by these two processes. You need to
use semaphores to avoid race conditions.
2|Page
17103057 CSX - 354
Practical -1
AIM : Write down the installation steps for ns3 simulator across Ubuntu and demonstrate the
installation steps using suitable snapshots.
Theory : NS-3 is a discrete-event network simulator, targeted primarily for research and
educational use. ns-3 software infrastructure encourages the development of simulation
models that are sufficiently realistic to allow ns-3 to be used as a real-time network emulator,
interconnected with the real world, and that allows many existing real-world protocol
implementations to be reused within ns-3.
Steps to download ns-3 :
NS-3 requires some pre-requisites to be installed in linux.
The following commands are typed in the terminal in order to download the
required repositories.
$ sudo apt-get install gcc g++ python- to download gcc compiler and python.
$ sudo apt-get install python-dev- to download and install the python development
environment.
$ mkdir NS3repo,$ cd NS3repo-creates a directory for downloading files.
$ hg clone http://code.nsnam.org/ns-3-allinone- clones the ns3-all in one files to
the repository.
./build.py-to compile,run and build python file.
./test.py-to check installation by running the python file.
3|Page
17103057 CSX - 354
Fig 1.1- Installation of packages.
Fig 1.2-Problems encountered while installation.
4|Page
17103057 CSX - 354
Fig 1.2-Build modules configured.
5|Page
17103057 CSX - 354
Practical-02
AIM : Learn the configuration of netanim with ns-3 simulator.
Theory : NS-3 makes use of network simulator called net-anim which helps in visualizing
network connections. It processes xml files for graphical output which are generated through
NS-3. The connection system are represented as nodes.
Steps for downloading, installing and configuring netanim
sudo apt-get install netanim – this command helps in downloading netanim
simulator from the terminal.
Now move to the netanim installation directory using cd ns-3.30-allinone/netanim.
/waf -d debug – helps to debug build configuration modules.
Netanim has been successfully installed on the system.It can be started using
./NetAnim command.
6|Page
17103057 CSX - 354
Fig 2.1- Including the main files.
Fig 2.2- Configuring the build modules
7|Page
17103057 CSX - 354
Fig 2.3 – Netanim installed successfully.
8|Page
17103057 CSX - 354
Practical – 03
AIM : Demonstrate the client server interaction using two nodes , communicating through
UDP in ns-3 simulator.
Program :
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"
using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");
int main (int argc, char *argv[])
{
CommandLine cmd;
cmd.Parse (argc, argv);
Time::SetResolution (Time::NS);
LogComponentEnable ("UdpEchoClientApplication",
LOG_LEVEL_INFO);
LogComponentEnable ("UdpEchoServerApplication",
LOG_LEVEL_INFO);
NodeContainer nodes;
nodes.Create (2);
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue
("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue
("2ms"));
9|Page
17103057 CSX - 354
NetDeviceContainer devices;
devices = pointToPoint.Install (nodes);
InternetStackHelper stack;
stack.Install (nodes);
Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer interfaces = address.Assign
(devices);
UdpEchoServerHelper echoServer (9);
ApplicationContainer serverApps = echoServer.Install
(nodes.Get (1));
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));
UdpEchoClientHelper echoClient (interfaces.GetAddress (1),
9);
echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
echoClient.SetAttribute ("Interval", TimeValue (Seconds
(1.0)));
echoClient.SetAttribute ("PacketSize", UintegerValue
(1024));
ApplicationContainer clientApps = echoClient.Install
(nodes.Get (0));
clientApps.Start (Seconds (2.0));
clientApps.Stop (Seconds (10.0));
Simulator::Run ();
Simulator::Destroy ();
return 0;
}
10 | P a g e
17103057 CSX - 354
Fig 3.1 – Data transfer between two nodes using ns-3 simulator.
Fig 3.2 – Graphical representation of data transfer between two nodes using netanim.
11 | P a g e
17103057 CSX - 354
Practical -04
AIM : Using the ns-3 simulator animate the desired network topology for UDP
communication.
Program:
// Default Network Topology
//
// 10.1.1.0
// n0 -------------- n1 n2 n3 n4
// point-to-point | | | |
// ================
// LAN 10.1.2.0
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/csma-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"
#include "ns3/ipv4-global-routing-helper.h"
using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("SecondScriptExample");
int
main (int argc, char *argv[])
{
bool verbose = true;
uint32_t nCsma = 3;
CommandLine cmd;
cmd.AddValue ("nCsma", "Number of \"extra\" CSMA
nodes/devices", nCsma);
12 | P a g e
17103057 CSX - 354
cmd.AddValue ("verbose", "Tell echo applications to log if
true", verbose);
cmd.Parse (argc,argv);
if (verbose)
{
LogComponentEnable ("UdpEchoClientApplication",
LOG_LEVEL_INFO);
LogComponentEnable ("UdpEchoServerApplication",
LOG_LEVEL_INFO);
}
nCsma = nCsma == 0 ? 1 : nCsma;
NodeContainer p2pNodes;
p2pNodes.Create (2);
NodeContainer csmaNodes;
csmaNodes.Add (p2pNodes.Get (1));
csmaNodes.Create (nCsma);
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue
("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue
("2ms"));
NetDeviceContainer p2pDevices;
p2pDevices = pointToPoint.Install (p2pNodes);
CsmaHelper csma;
csma.SetChannelAttribute ("DataRate", StringValue
("100Mbps"));
13 | P a g e
17103057 CSX - 354
csma.SetChannelAttribute ("Delay", TimeValue (NanoSeconds
(6560)));
NetDeviceContainer csmaDevices;
csmaDevices = csma.Install (csmaNodes);
InternetStackHelper stack;
stack.Install (p2pNodes.Get (0));
stack.Install (csmaNodes);
Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer p2pInterfaces;
p2pInterfaces = address.Assign (p2pDevices);
address.SetBase ("10.1.2.0", "255.255.255.0");
Ipv4InterfaceContainer csmaInterfaces;
csmaInterfaces = address.Assign (csmaDevices);
UdpEchoServerHelper echoServer (9);
ApplicationContainer serverApps = echoServer.Install
(csmaNodes.Get (nCsma));
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));
UdpEchoClientHelper echoClient (csmaInterfaces.GetAddress
(nCsma), 9);
echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
echoClient.SetAttribute ("Interval", TimeValue (Seconds
(1.0)));
echoClient.SetAttribute ("PacketSize", UintegerValue
(1024));
14 | P a g e
17103057 CSX - 354
ApplicationContainer clientApps = echoClient.Install
(p2pNodes.Get (0));
clientApps.Start (Seconds (2.0));
clientApps.Stop (Seconds (10.0));
Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
pointToPoint.EnablePcapAll ("second");
csma.EnablePcap ("second", csmaDevices.Get (1), true);
Simulator::Run ();
Simulator::Destroy ();
return 0;
}
Fig 4 – Data transfer between two nodes using ns-3 simulator.
15 | P a g e
17103057 CSX - 354
Practical -05
AIM : Using the built-in library examples, illustrate the client interaction using a server and
router enabling UDP data transfer.
Program :
#include "ns3/netanim-module.h"
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"
using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");
int
main (int argc, char *argv[])
{
Time::SetResolution (Time::NS);
LogComponentEnable ("UdpEchoClientApplication",
LOG_LEVEL_INFO);
LogComponentEnable ("UdpEchoServerApplication",
LOG_LEVEL_INFO);
NodeContainer nodes;
nodes.Create (3);
InternetStackHelper stack;
stack.Install (nodes);
PointToPointHelper p2p1;
p2p1.SetDeviceAttribute ("DataRate", StringValue
("5Mbps"));
16 | P a g e
17103057 CSX - 354
p2p1.SetChannelAttribute ("Delay", StringValue ("1ms"));
PointToPointHelper p2p2;
p2p2.SetDeviceAttribute ("DataRate", StringValue
("10Mbps"));
p2p2.SetChannelAttribute ("Delay", StringValue ("5ms"));
Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.0");
NetDeviceContainer devices;
devices = p2p1.Install (nodes.Get (0), nodes.Get (1));
Ipv4InterfaceContainer interfaces = address.Assign
(devices);
devices = p2p2.Install (nodes.Get (1), nodes.Get (2));
address.SetBase ("10.1.2.0", "255.255.255.0");
interfaces = address.Assign (devices);
Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
UdpEchoServerHelper echoServer (9);
ApplicationContainer serverApps = echoServer.Install
(nodes.Get (2));
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));
UdpEchoClientHelper echoClient (interfaces.GetAddress
(1), 9);
echoClient.SetAttribute ("MaxPackets", UintegerValue
(1));
echoClient.SetAttribute ("Interval", TimeValue (Seconds
(1.0)));
17 | P a g e
17103057 CSX - 354
echoClient.SetAttribute ("PacketSize", UintegerValue
(1024));
ApplicationContainer clientApps = echoClient.Install
(nodes.Get (0));
clientApps.Start (Seconds (2.0));
clientApps.Stop (Seconds (10.0));
AnimationInterface anim ("my_example_1.xml");
anim.SetConstantPosition (nodes.Get(0), 0.0, 0.0);
anim.SetConstantPosition (nodes.Get(1), 2.0, 2.0);
anim.SetConstantPosition (nodes.Get(2), 3.0, 3.0);
Simulator::Run ();
Simulator::Destroy ();
return 0;
}
Fig 5 – Data transfer between two nodes with router as intermediate using NS-3
18 | P a g e
17103057 CSX - 354
Practical-06
AIM : Write down a C program demonstrating the use of Process IDs at Ubuntu terminal for
multiple process applications.
Program :
#include <iostream>
#include <unistd.h>
using namespace std;
// Driver Code
int main()
int pid;
pid = fork();
if (pid == 0)
cout << "\nParent Process id : "
<< getpid() << endl;
cout << "\nChild Process with parent id : "
<< getppid() << endl;
return 0;
19 | P a g e
17103057 CSX - 354
Fig 6 – Printing process id and parent id of process
20 | P a g e
17103057 CSX - 354
Practical -07
AIM : Demonstrate the implementation of Pipes for IPC in between client server processes
using C language programs.
Program:
// Client side program for pipe implementation
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#define PORT 8080
int main(int argc, char const *argv[])
{
int sock = 0, valread;
struct sockaddr_in serv_addr;
char *hello = "Hello from client";
char buffer[1024] = {0};
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Socket creation error \n");
return -1;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
if(inet_pton(AF_INET, "127.0.0.1",
&serv_addr.sin_addr)<=0)
{
printf("\nInvalid address/ Address not supported
\n");
return -1;
}
if (connect(sock, (struct sockaddr *)&serv_addr,
sizeof(serv_addr)) < 0)
{
printf("\nConnection Failed \n");
return -1;
}
21 | P a g e
17103057 CSX - 354
send(sock , hello , strlen(hello) , 0 );
printf("Hello message sent\n");
valread = read( sock , buffer, 1024);
printf("%s\n",buffer );
return 0;
}
//Server-side program for pipe implementation
#include <unistd.h>
#include<string.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#define PORT 8080
int main(int argc, char const *argv[])
{
int server_fd, new_socket, valread;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[1024] = {0};
char *hello ="hello";
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
{
perror("socket failed");
exit(EXIT_FAILURE);
}
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR |
SO_REUSEPORT,
&opt, sizeof(opt)))
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons( PORT );
if (bind(server_fd, (struct sockaddr *)&address,
sizeof(address))<0)
22 | P a g e
17103057 CSX - 354
{
perror("bind failed");
exit(EXIT_FAILURE);
}
if (listen(server_fd, 3) < 0)
{
perror("listen");
exit(EXIT_FAILURE);
}
if ((new_socket = accept(server_fd, (struct sockaddr
*)&address,
(socklen_t*)&addrlen))<0)
{
perror("accept");
exit(EXIT_FAILURE);
}
valread = read( new_socket , buffer, 1024);
printf("%s\n",buffer );
send(new_socket , hello , strlen(hello) , 0 );
printf(" message sent\n");
return 0;
}
Fig 7 – Communication between two terminals using pipe implementation.
23 | P a g e
17103057 CSX - 354
Practical – 08
AIM : Demonstrate the implementation of FIFOs for IPC in between client server processes
using C language programs.
Program:
//Client side program for FIFO implementation
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
int fd;
// FIFO file path
char * myfifo = "/tmp/myfifo";
// Creating the named file(FIFO)
// mkfifo(<pathname>, <permission>)
mkfifo(myfifo, 0666);
char arr1[80], arr2[80];
while (1)
{
// Open FIFO for write only
fd = open(myfifo, O_WRONLY);
// Take an input arr2ing from user.
// 80 is maximum length
fgets(arr2, 80, stdin);
// Write the input arr2ing on FIFO
// and close it
write(fd, arr2, strlen(arr2)+1);
close(fd);
// Open FIFO for Read only
24 | P a g e
17103057 CSX - 354
fd = open(myfifo, O_RDONLY);
// Read from FIFO
read(fd, arr1, sizeof(arr1));
// Print the read message
printf("User2: %s\n", arr1);
close(fd);
}
return 0;
}
//Server side program for FIFO implementation
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
int fd1;
char * myfifo = "/tmp/myfifo";
// Creating the named file(FIFO)
// mkfifo(<pathname>,<permission>)
mkfifo(myfifo, 0666);
char str1[80], str2[80];
while (1)
{
// First open in read only and read
fd1 = open(myfifo,O_RDONLY);
read(fd1, str1, 80);
// Print the read string and close
printf("User1: %s\n", str1);
close(fd1);
// Now open in write mode and write
// string taken from user.
25 | P a g e
17103057 CSX - 354
fd1 = open(myfifo,O_WRONLY);
fgets(str2, 80, stdin);
write(fd1, str2, strlen(str2)+1);
close(fd1);
}
return 0;
}
Fig 8 – Communication between two terminals using FIFO implementation.
26 | P a g e
17103057 CSX - 354
Practical -09
AIM : Demonstrate the implementation of message queues for IPC in between client server
processes using C language programs.
Program :
//Reader program for implementation of message queues
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct mesg_buffer {
long mesg_type;
char mesg_text[100];
} message;
int main()
{
key_t key;
int msgid;
// ftok to generate unique key
key = ftok("progfile", 65);
// msgget creates a message queue
// and returns identifier
msgid = msgget(key, 0666 | IPC_CREAT);
msgrcv(msgid, &message, sizeof(message), 1, 0);
printf("Data Received is : %s \n",
message.mesg_text);
msgctl(msgid, IPC_RMID, NULL);
return 0;
}
27 | P a g e
17103057 CSX - 354
//Writer program for implementation of message queues
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct mesg_buffer
{
long mesg_type;
char mesg_text[100];
} message;
int main()
{
key_t key;
int msgid;
key = ftok("progfile", 65);
//generates a unique key
msgid = msgget(key, 0666 | IPC_CREAT);
message.mesg_type = 1;
printf("Write Data : ");
gets(message.mesg_text);
// msgsnd to send message
msgsnd(msgid, &message, sizeof(message), 0);
// display the message
printf("Data send is : %s \n", message.mesg_text);
return 0;
}
Fig 9 – Data transfer between two terminals using message queues.
28 | P a g e
17103057 CSX - 354
Practical -10
AIM : Write two programs one each for client and server to create an integer variable using
shared memory concept and increment the variable simultaneously by these two
processes. You need to use semaphores to avoid the race conditions.
Program:
//Client program for shared memory using semaphores.
#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<sys/sem.h>
#include<string.h>
#include<errno.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#define SHM_KEY 0x12345
#define SEM_KEY 0x54321
#define MAX_TRIES 20
struct shmseg {
int cntr;
int write_complete;
int read_complete;
};
void shared_memory_cntr_increment(int, struct shmseg*, int);
void remove_semaphore();
int main(int argc, char *argv[]) {
int shmid;
struct shmseg *shmp;
char *bufptr;
int total_count;
int sleep_time;
pid_t pid;
if (argc != 2)
total_count = 10000;
else {
total_count = atoi(argv[1]);
29 | P a g e
17103057 CSX - 354
if (total_count < 10000)
total_count = 10000;
}
printf("Total Count is %d\n", total_count);
shmid = shmget(SHM_KEY, sizeof(struct shmseg), 0644|
IPC_CREAT);
if (shmid == -1) {
perror("Shared memory");
return 1;
}
// Attach to the segment to get a pointer to it.
shmp = shmat(shmid, NULL, 0);
if (shmp == (void *) -1) {
perror("Shared memory attach: ");
return 1;
}
shmp->cntr = 0;
pid = fork();
/* Parent Process - Writing Once */
if (pid > 0) {
shared_memory_cntr_increment(pid, shmp, total_count);
} else if (pid == 0) {
shared_memory_cntr_increment(pid, shmp, total_count);
return 0;
} else {
perror("Fork Failure\n");
return 1;
}
while (shmp->read_complete != 1)
sleep(1);
if (shmdt(shmp) == -1) {
perror("shmdt");
return 1;
}
if (shmctl(shmid, IPC_RMID, 0) == -1) {
perror("shmctl");
return 1;
}
printf("Writing Process: Complete\n");
30 | P a g e
17103057 CSX - 354
remove_semaphore();
return 0;
}
/* Increment the counter of shared memory by total_count in
steps of 1 */
void shared_memory_cntr_increment(int pid, struct shmseg
*shmp, int total_count) {
int cntr;
int numtimes;
int sleep_time;
int semid;
struct sembuf sem_buf;
struct semid_ds buf;
int tries;
int retval;
semid = semget(SEM_KEY, 1, IPC_CREAT | IPC_EXCL | 0666);
//printf("errno is %d and semid is %d\n", errno, semid);
/* Got the semaphore */
if (semid >= 0) {
printf("First Process\n");
sem_buf.sem_op = 1;
sem_buf.sem_flg = 0;
sem_buf.sem_num = 0;
retval = semop(semid, &sem_buf, 1);
if (retval == -1) {
perror("Semaphore Operation: ");
return;
}
} else if (errno == EEXIST) { // Already other process got
it
int ready = 0;
printf("Second Process\n");
semid = semget(SEM_KEY, 1, 0);
if (semid < 0) {
perror("Semaphore GET: ");
return;
}
/* Waiting for the resource */
sem_buf.sem_num = 0;
sem_buf.sem_op = 0;
sem_buf.sem_flg = SEM_UNDO;
31 | P a g e
17103057 CSX - 354
retval = semop(semid, &sem_buf, 1);
if (retval == -1) {
perror("Semaphore Locked: ");
return;
}
}
sem_buf.sem_num = 0;
sem_buf.sem_op = -1; /* Allocating the resources */
sem_buf.sem_flg = SEM_UNDO;
retval = semop(semid, &sem_buf, 1);
if (retval == -1) {
perror("Semaphore Locked: ");
return;
}
cntr = shmp->cntr;
shmp->write_complete = 0;
if (pid == 0)
printf("SHM_WRITE: CHILD: Now writing\n");
else if (pid > 0)
printf("SHM_WRITE: PARENT: Now writing\n");
//printf("SHM_CNTR is %d\n", shmp->cntr);
/* Increment the counter in shared memory by total_count in
steps of 1 */
for (numtimes = 0; numtimes < total_count; numtimes++) {
cntr += 1;
shmp->cntr = cntr;
/* Sleeping for a second for every thousand */
sleep_time = cntr % 1000;
if (sleep_time == 0)
sleep(1);
}
shmp->write_complete = 1;
sem_buf.sem_op = 1; /* Releasing the resource */
retval = semop(semid, &sem_buf, 1);
if (retval == -1) {
perror("Semaphore Locked\n");
return;
}
if (pid == 0)
printf("SHM_WRITE: CHILD: Writing Done\n");
32 | P a g e
17103057 CSX - 354
else if (pid > 0)
printf("SHM_WRITE: PARENT: Writing Done\n");
return;
}
void remove_semaphore() {
int semid;
int retval;
semid = semget(SEM_KEY, 1, 0);
if (semid < 0) {
perror("Remove Semaphore: Semaphore GET: ");
return;
}
retval = semctl(semid, 0, IPC_RMID);
if (retval == -1) {
perror("Remove Semaphore: Semaphore CTL: ");
return;
}
return;
}
//Server program for shared memory using semaphores.
/* Filename: shm_read_cntr.c */
#include<stdio.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<sys/types.h>
#include<string.h>
#include<errno.h>
#include<stdlib.h>
#include<unistd.h>
#define SHM_KEY 0x12345
struct shmseg {
int cntr;
int write_complete;
int read_complete;
};
int main(int argc, char *argv[]) {
int shmid, numtimes;
struct shmseg *shmp;
int total_count;
int cntr;
33 | P a g e
17103057 CSX - 354
int sleep_time;
if (argc != 2)
total_count = 10000;
else {
total_count = atoi(argv[1]);
if (total_count < 10000)
total_count = 10000;
}
shmid = shmget(SHM_KEY, sizeof(struct shmseg), 0644|
IPC_CREAT);
if (shmid == -1) {
perror("Shared memory");
return 1;
}
// Attach to the segment to get a pointer to it.
shmp = shmat(shmid, NULL, 0);
if (shmp == (void *) -1) {
perror("Shared memory attach");
return 1;
}
while (shmp->write_complete != 1) {
if (shmp->cntr == -1) {
perror("read");
return 1;
}
sleep(3);
}
printf("Reading Process: Shared Memory: Counter is %d\n",
shmp->cntr);
printf("Reading Process: Reading Done, Detaching Shared
Memory\n");
shmp->read_complete = 1;
if (shmdt(shmp) == -1) {
perror("shmdt");
return 1;
}
printf("Reading Process: Complete\n");
return 0;
}
34 | P a g e
17103057 CSX - 354
Fig 10 – Data transfer between two terminals semaphores and shared memory
35 | P a g e