Roll No: 160122733028 Exp.
No: 06 Date: 14-10-24
Lab Task – 6
Linux offers several Inter-Process Communication (IPC) mechanisms,
including pipes, message queues, shared memory, semaphores, and sockets.
Below are example programs for some common IPC mechanisms in Linux.
1. Unnamed Pipe
Aim: To Write a program and to demonstrate named and unnamed pipes for IPC.
Description: An unnamed pipe is used for communication between processes that
share a common ancestry (parent-child).
Code:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h> // For wait()
int main() {
int pipefds[2];
char write_msg[100];
char read_msg[100];
// Create pipe
if (pipe(pipefds) == -1) {
perror("pipe");
return 1;
}
pid_t pid = fork();
if (pid == -1) {
perror("fork");
return 1;
}
if (pid == 0) {
// Child process: Reads from the pipe
close(pipefds[1]); // Close unused write end
read(pipefds[0], read_msg, sizeof(read_msg)); // Read from pipe
printf("Child received: %s\n", read_msg); // Print received message
close(pipefds[0]); // Close read end
} else {
// Parent process: Gets input from the user and writes to the pipe
close(pipefds[0]); // Close unused read end
printf("Enter a message: ");
Page No. ………50……….. Signature of the Faculty………………………...
Roll No: 160122733028 Exp. No: 06 Date: 14-10-24
fgets(write_msg, sizeof(write_msg), stdin); // Get input from user
write(pipefds[1], write_msg, strlen(write_msg) + 1); // Write to pipe
close(pipefds[1]); // Close write end
wait(NULL); // Wait for child to finish
}
return 0;
}
OUTPUT:
1.Named Pipe
Aim: To Write a program and to demonstrate named and named pipes for IPC.
Description: Named pipes (also called FIFOs) allow unrelated processes to
communicate. First, create the FIFO file using mkfifo command:
bash
mkfifo /tmp/myfifo
Then, two separate programs can communicate through the FIFO.
Code:
Writer.c
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
int fd;
char write_msg[100];
// Open the FIFO for writing
fd = open("myfifo", O_WRONLY);
if (fd == -1) {
perror("open");
return 1;
}
Page No. ………51……….. Signature of the Faculty………………………...
Roll No: 160122733028 Exp. No: 06 Date: 14-10-24
// Get user input
printf("Enter a message: ");
fgets(write_msg, sizeof(write_msg), stdin);
// Write to the FIFO
write(fd, write_msg, sizeof(write_msg));
// Close the FIFO
close(fd);
return 0;
}
Reader.c
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
int fd;
char read_msg[100];
// Open the FIFO for reading
fd = open("myfifo", O_RDONLY);
if (fd == -1) {
perror("open");
return 1;
}
// Read from the FIFO
read(fd, read_msg, sizeof(read_msg));
// Print the received message
printf("Received: %s\n", read_msg);
// Close the FIFO
close(fd);
return 0;
}
Output:
Page No. ………52……….. Signature of the Faculty………………………...
Roll No: 160122733028 Exp. No: 06 Date: 14-10-24
3. Aim: To Write a program to demonstrate IPC using shared memory.
Description: Implement shared memory for communication between processes
by attaching, reading, and writing data..
Code:
Writer.c
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <unistd.h>
int main() {
// Generate a unique key for shared memory
key_t key = ftok("shmfile", 65);
// Create a shared memory segment with a size of 1024 bytes
int shmid = shmget(key, 1024, 0666|IPC_CREAT);
// Attach the shared memory segment to this process's address space
char *str = (char*) shmat(shmid, (void*)0, 0);
// Write data to shared memory
printf("Enter a message to write to shared memory: ");
fgets(str, 1024, stdin); // Write user input to shared memory
printf("Data written to shared memory: %s\n", str);
// Detach from the shared memory segment
shmdt(str);
return 0;
}
Reader.c
Page No. ………53……….. Signature of the Faculty………………………...
Roll No: 160122733028 Exp. No: 06 Date: 14-10-24
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
int main() {
// Generate the same unique key
key_t key = ftok("shmfile", 65);
// Access the shared memory segment created by the writer
int shmid = shmget(key, 1024, 0666);
// Attach the shared memory segment to this process's address space
char *str = (char*) shmat(shmid, (void*)0, 0);
// Read and print the data from shared memory
printf("Data read from shared memory: %s\n", str);
// Detach from the shared memory segment
shmdt(str);
// Destroy the shared memory segment after reading
shmctl(shmid, IPC_RMID, NULL);
return 0;
}
Output:
4. Aim: Write a program to demonstrate IPC using message queues.
Description: Use message queues to send and receive messages between two or more
processes.
Code:
Sender.c
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
Page No. ………54……….. Signature of the Faculty………………………...
Roll No: 160122733028 Exp. No: 06 Date: 14-10-24
// Define the structure of the message
struct msg_buffer {
long msg_type;
char msg_text[100];
} message;
int main() {
key_t key;
int msgid;
// Generate a unique key for the message queue
key = ftok("progfile", 65);
// Create a message queue and return its ID
msgid = msgget(key, 0666 | IPC_CREAT);
message.msg_type = 1; // Message type, must be positive
// Get input from the user
printf("Enter a message: ");
fgets(message.msg_text, sizeof(message.msg_text), stdin);
// Send the message to the queue
msgsnd(msgid, &message, sizeof(message), 0);
printf("Message sent: %s", message.msg_text);
return 0;
}
Receiver.c
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
// Define the structure of the message
struct msg_buffer {
long msg_type;
char msg_text[100];
Page No. ………55……….. Signature of the Faculty………………………...
Roll No: 160122733028 Exp. No: 06 Date: 14-10-24
} message;
int main() {
key_t key;
int msgid;
// Generate the same unique key as the sender
key = ftok("progfile", 65);
// Access the message queue using the key
msgid = msgget(key, 0666 | IPC_CREAT);
// Receive the message from the queue
msgrcv(msgid, &message, sizeof(message), 1, 0);
// Print the received message
printf("Message received: %s", message.msg_text);
// Destroy the message queue after receiving the message
msgctl(msgid, IPC_RMID, NULL);
return 0;
}
Output:
5. Aim:To Write a program to demonstrate IPC using semaphores
Description: Implement semaphores for process synchronization, ensuring
mutual exclusion.
Code:
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/wait.h> // For wait()
Page No. ………56……….. Signature of the Faculty………………………...
Roll No: 160122733028 Exp. No: 06 Date: 14-10-24
#include <unistd.h>
// Define union semun for semaphore control operations
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
};
// Function to perform the "wait" (P) operation on the semaphore
void semaphore_wait(int semid) {
struct sembuf sem_op;
sem_op.sem_num = 0; // Semaphore index in the semaphore set
sem_op.sem_op = -1; // Decrement the semaphore (P operation)
sem_op.sem_flg = 0; // No special options
semop(semid, &sem_op, 1); // Perform the semaphore operation
}
// Function to perform the "signal" (V) operation on the semaphore
void semaphore_signal(int semid) {
struct sembuf sem_op;
sem_op.sem_num = 0; // Semaphore index in the semaphore set
sem_op.sem_op = 1; // Increment the semaphore (V operation)
sem_op.sem_flg = 0; // No special options
semop(semid, &sem_op, 1); // Perform the semaphore operation
}
int main() {
key_t key = ftok("semfile", 65); // Generate a unique key
int semid = semget(key, 1, 0666 | IPC_CREAT); // Create a semaphore set with
one semaphore
// Initialize the semaphore value to 1 (critical section available)
union semun sem_union;
sem_union.val = 1;
semctl(semid, 0, SETVAL, sem_union);
if (fork() == 0) {
// Child process
semaphore_wait(semid); // Enter critical section
Page No. ………57……….. Signature of the Faculty………………………...
Roll No: 160122733028 Exp. No: 06 Date: 14-10-24
printf("Child process is in critical section\n");
sleep(2); // Simulate work in the critical section
semaphore_signal(semid); // Leave critical section
printf("Child process is leaving critical section\n");
} else {
// Parent process
semaphore_wait(semid); // Enter critical section
printf("Parent process is in critical section\n");
sleep(2); // Simulate work in the critical section
semaphore_signal(semid); // Leave critical section
printf("Parent process is leaving critical section\n");
wait(NULL); // Wait for child to finish
// Remove the semaphore set after the processes have completed
semctl(semid, 0, IPC_RMID);
}
return 0;
}
Output:
6. Aim: Write a program to demonstrate signal generation and
handling. Description: Handle and generate signals like SIGINT to
manage interprocess communication.
Code:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
// Signal handler for SIGINT
Page No. ………58……….. Signature of the Faculty………………………...
Roll No: 160122733028 Exp. No: 06 Date: 14-10-24
void handle_sigint(int sig) {
printf("Caught signal %d (SIGINT). Exiting gracefully...\n", sig);
// Perform any cleanup if necessary
_exit(0); // Exit the program
}
int main() {
// Register signal handler for SIGINT
signal(SIGINT, handle_sigint);
printf("Press Ctrl+C to generate SIGINT signal...\n");
// Infinite loop to keep the program running
while (1) {
printf("Program is running... Press Ctrl+C to send SIGINT\n");
sleep(1); // Sleep for a while to prevent spamming output
}
return 0;
}
Output:
7. Aim: A program to demonstrate the use of socket – IPC
Description: A socket is a bi-directional data transfer mechanism.
They are used to transfer data between two processes. The two
processes can be running on the same system as Unix-domain or
loopback sockets, or on different systems as network sockets.
Code:
Socket:
#include <stdio.h>
#include <netdb.h>
#include <netinet/in.h>
Page No. ………59……….. Signature of the Faculty………………………...
Roll No: 160122733028 Exp. No: 06 Date: 14-10-24
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#define MAX 80
#define PORT 8080
#define SA struct sockaddr
// Function designed for chat between client and server.
void func(int connfd) {
char buff[MAX];
int n;
// Infinite loop for chat
for (;;) {
bzero(buff, MAX);
// Read the message from client and copy it in buffer
read(connfd, buff, sizeof(buff));
// Print buffer which contains the client contents
printf("From client: %s\t To client: ", buff);
bzero(buff, MAX);
n = 0;
// Copy server message in the buffer
while ((buff[n++] = getchar()) != '\n')
;
// Send that buffer to client
write(connfd, buff, sizeof(buff));
// If msg contains "exit" then server exit and chat ended.
if (strncmp("exit", buff, 4) == 0) {
printf("Server Exit...\n");
break;
}
}
}
// Driver function
Page No. ………60……….. Signature of the Faculty………………………...
Roll No: 160122733028 Exp. No: 06 Date: 14-10-24
int main() {
int sockfd, connfd, len;
struct sockaddr_in servaddr, cli;
// Socket create and verification
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
printf("Socket creation failed...\n");
exit(0);
} else {
printf("Socket successfully created..\n");
}
bzero(&servaddr, sizeof(servaddr));
// Assign IP, PORT
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(PORT);
// Binding newly created socket to given IP and verification
if ((bind(sockfd, (SA*)&servaddr, sizeof(servaddr))) != 0) {
printf("Socket bind failed...\n");
exit(0);
} else {
printf("Socket successfully binded..\n");
}
// Now server is ready to listen and verification
if ((listen(sockfd, 5)) != 0) {
printf("Listen failed...\n");
exit(0);
} else {
printf("Server listening..\n");
}
len = sizeof(cli);
// Accept the data packet from client and verification
connfd = accept(sockfd, (SA*)&cli, &len);
if (connfd < 0) {
printf("Server accept failed...\n");
exit(0);
Page No. ………61……….. Signature of the Faculty………………………...
Roll No: 160122733028 Exp. No: 06 Date: 14-10-24
} else {
printf("Server accepted the client...\n");
}
// Function for chatting between client and server
func(connfd);
// After chatting, close the socket
close(sockfd);
}
Client:
#include <arpa/inet.h> // inet_addr()
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h> // bzero()
#include <sys/socket.h>
#include <unistd.h> // read(), write(), close()
#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");
Page No. ………62……….. Signature of the Faculty………………………...
Roll No: 160122733028 Exp. No: 06 Date: 14-10-24
break;
}
}
}
int main() {
int sockfd;
struct sockaddr_in servaddr;
// Socket create and verification
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
printf("Socket creation failed...\n");
exit(0);
} else {
printf("Socket successfully created..\n");
}
bzero(&servaddr, sizeof(servaddr));
// Assign IP, PORT
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servaddr.sin_port = htons(PORT);
// Connect the client socket to server socket
if (connect(sockfd, (SA*)&servaddr, sizeof(servaddr)) != 0) {
printf("Connection with the server failed...\n");
exit(0);
} else {
printf("Connected to the server..\n");
}
// Function for chat
func(sockfd);
// Close the socket
close(sockfd);
}
Output:
Page No. ………63……….. Signature of the Faculty………………………...
Roll No: 160122733028 Exp. No: 06 Date: 14-10-24
Page No. ………64……….. Signature of the Faculty………………………...