Posts: 5,362
Threads: 2,998
Joined: Feb 2011
Presented by:
Vetrivel.M
Asai Thambi.M
Sivaguru.R
Selvan.G.B
Karthikeyan.V.B
Pravin.P
[attachment=12288]
INTERPROCESS COMMUICATION
Introduction
Named pipes allow two unrelated processes to communicate with each other. They are also known as FIFOs (first-in, first-out) and can be used to establish a one-way (half-duplex) flow of data.
Named pipes are identified by their access point, which is basically in a file kept on the file system.
Named pipes are file system-persistent objects.
In order to communicate by means of a named pipe, the processes have to open the file associated with the named pipe.
By opening the file for reading, the process has access to the reading end of the pipe,
By opening the file for writing, the process has access to the writing end of the pipe.
A named pipe must be opened either read-only or write-only.
It must not be opened for read-write because it is half-duplex, that is, a one-way channel.
Creating a Named Pipe
A named pipe can be created in two ways – via
the command line or from within a program.
From the Command Line
A named pipe may be created from the
shell command line.
Use either "mknod“ or "mkfifo“ commands.
Example:
To create a named pipe with the file named "npipe“
$ mknod npipe p
or
$ mkfifo npipe
Within a Program
The function "mkfifo"can be used to create a named pipe from within a program.
int mkfifo(const char *path, mode_t mode)
It creates a new named pipe or returns an error of EEXIST if the named pipe already exists.
The named pipe's owner ID is set to the process'effective user ID, and its group ID is set to the process'effective group ID.
Opening a Named Pipe
A named pipe can be opened for reading or writing.
A named pipe can be opened by using the open() system call, or by using the fopen() standard C library function.
If the call succeeds, file descriptor is got in the case of open(), or a 'FILE‘ structure pointer in the case of fopen().
Reading From and Writing to a Named Pipe
Using Half-Duplex Communication
The standard C library function calls read( )and write( )can be used for reading from and writing to a named pipe.
A named pipe cannot be opened for both reading and writing.
The process opening it must choose either read mode or write mode.
The pipe opened in one mode will remain in that mode until it is closed.
Read and write operations to a named pipe are blocking, by default.
Therefore if a process reads from a named pipe and if the pipe does not have data in it, the reading process will be blocked.
Similarly if a process tries to write to a named pipe that has no reader, the writing process gets blocked, until another process opens the named pipe for reading.
Filename : half_duplex.h
#define HALF_DUPLEX "/tmp/halfduplex"
#define MAX_BUF_SIZE> 255
Server Code
The following code shows the contents of Filename:
hd_server.c
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <half_duplex.h>
int main(int argc, char *argv[])
{
int fd, ret_val, count, numread;
char buf[MAX_BUF_SIZE];
/* Create the named - pipe */
ret_val = mkfifo(HALF_DUPLEX, 0666);
if ((ret_val == -1) &&(errno != EEXIST)) {
perror("Error creating the named pipe");
exit (1);
}
Client Code
The following table shows the contents of Filename : hd_client.c.
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <halfduplex.h>/* For name of the named-pipe */
int main(int argc, char *argv[])
{
int fd;
/* Check if an argument was specified. */
if (argc != 2) {
printf("Usage : %s <string to be sent to the server>n", argv[0]);
exit (1);
}
/* Open the pipe for writing */
fd = open(HALF_DUPLEX, O_WRONLY);
/* Write to the pipe */
write(fd, argv[1], strlen(argv[1]));
}
Running the Client and the Server
When you run the server, it will block on the read call and will wait until the client writes something to the named pipe.
After that it will print what it read from the pipe, convert the string to upper case, and then terminate.
Run the server:
$ hd_server &
The server program will block here, and the shell will return control to the command line.
Run the client:
hd_client hello
The server prints the string read and terminates:
Half Duplex Server : Read From the pipe : hello
Half Duplex Server : Converted String : HELLO
Full-Duplex Communication Using Named Pipes
Full-duplex communication à by using two different named pipes, so each named pipe provides the flow of data in one direction.
For example, consider two named pipes:
NP1 and NP2
In order to establish a full-duplex channel, here is how the server and the client should treat these two named pipes:
Let us assume that
The server opens the named pipe NP1 for reading and
The second pipe NP2 for writing.
The client must open the first named pipe NP1 for writing and
The second named pipe NP2 for reading.
This way a full-duplex channel can be established between the two processes.
Filename : fullduplex.h
#define NP1 "/tmp/np1"
#define NP2 "/tmp/np2"
#define MAX_BUF_SIZE 255
Server Code fd_server.c.
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <fullduplex.h>
int main(int argc, char *argv[])
{
int rdfd, wrfd, ret_val, count, numread;
char buf[MAX_BUF_SIZE];
/* Create the first named - pipe */
ret_val = mkfifo(NP1, 0666);
if ((ret_val == -1) &&(errno != EEXIST)) {
perror("Error creating the named pipe");
exit (1);
}
ret_val = mkfifo(NP2, 0666);
Client Code
The following table shows the contents of Filename : hd_client.c.
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <fullduplex.h>/* For name of the named-pipe */
int main(int argc, char *argv[])
{
int wrfd, rdfd, numread;
char rdbuf[MAX_BUF_SIZE];
if (argc != 2) {
printf("Usage : %s <string to be sent to the server>n", argv[0]);
exit (1);
}
/* Open the first named pipe for writing */
wrfd = open(NP1, O_WRONLY);
/* Open the second named pipe for reading */
rdfd = open(NP2, O_RDONLY);
/* Write to the pipe */
write(wrfd, argv[1], strlen(argv[1]));
/* Read from the pipe */
numread = read(rdfd, rdbuf, MAX_BUF_SIZE);
rdbuf[numread] = '0';
printf("Full Duplex Client : Read From the
Pipe : %sn", rdbuf);
}
Expected output:
Run the server:
$ fd_server &
The server program will block here, and the shell will return control to the command line.
Run the client:
$ fd_client hello
The client program will send the string to server and block on the read to await the server's response.
The server prints the following:
Full Duplex Server : Read From the pipe : hello
The client prints the following:
Full Duplex Client : Read From the pipe : HELLO
Summary
Implemented Inter-process communication
Using Named Pipes or FIFO’s
Creation,Opening and r/w operations are dealt
Half-duplex and full-duplex communication
In IPC