Inter-Process Communication with anonymous pipes, Part 01: transfer a byte stream

Inter-Process Communication is used by different processes to interact and share data with each other. Several possible ways exist to implement such an Inter-Process Communication. I have shown one possibility in a previous article: memory mapped files. Within this article I want to show another solution, based on anonymous pipes.

Beside the anonymous pipes there are also named pipes. One main difference between these two types is the network support. Named pipes support the communication over a network and anonymous pipes can only be used for communication between processes on the local PC. Within a next article of this series I will give you an introduction to named pipes.

 
Anonymous pipes

In summary a anonymous pipe has the following features:

  • One to one communication (parent-child communication)
  • One-way communication
  • Supports data transfer between local processes but does not not support communications over the network
  • Byte-stream oriented
  • Less functionality compared to named pipes, but easier to use

 

The pipe is implemented in a first-in-first-out manner. The parent process will write data to the pipe and the child process may read it. The data is passed to the child in the same order in which it was written. Once the data is read it is removed from the pipe.

The parent process creates the pipe(s) and the child process will use them. Therefore these pipe handles must be transferred from the parent to the child. A common way to do this is to pass the pipe handles to the child process.

An anonymous pipe provides a one-way communication between the processes. Therefore if a two-way communication is needed then two pipes have to be used.

 
Parent process

The following source code shows a console application which implements two anonymous pipes. One is used to send data and the other one to receive data. The handles of the pipes will be passed as parameters to the client process. In line 8 you have to set the path for the client application (which will be shown in the next section). After the client is started, the local copy of the pipe handles for the client will be released. Afterwards data in form of byte data is send to the client and response data is received.

static void Main(string[] args)
{
    //create streams
    var sender = new AnonymousPipeServerStream (PipeDirection.Out, HandleInheritability.Inheritable);
    var receiver = new AnonymousPipeServerStream (PipeDirection.In, HandleInheritability.Inheritable);
            
    //start client, pass pipe ids as command line parameter 
    string clientPath = @"...";
    string senderID = sender.GetClientHandleAsString();
    string receiverID = receiver.GetClientHandleAsString();

    var startInfo = new ProcessStartInfo (clientPath, senderID + " " + receiverID);
    startInfo.UseShellExecute = false;   
    Process clientProcess = Process.Start(startInfo);

    //release resources handlet by client
    sender.DisposeLocalCopyOfClientHandle();
    receiver.DisposeLocalCopyOfClientHandle();

    //write data
    byte dataSend = 48;
    sender.WriteByte(dataSend);
    Console.WriteLine("Parent send: " + dataSend.ToString());

    //read data
    int dataReceive = receiver.ReadByte();
    Console.WriteLine("Parent receive: " + dataReceive.ToString());

    //wait until client is closed
    clientProcess.WaitForExit();
    Console.WriteLine("Client execution finished");

    Console.ReadKey();
}

 
Child process

Within the child process, in this example implemented as console application, the process start arguments will be read. There are two arguments which were passed by the parent process. These arguments are the identifiers for the pipe handles. The client will create the pipes by using these identifiers. Then it is possible to receive the byte, send by the parent, and send some other byte back.

static void Main(string[] args)
{
    string parentSenderID;
    string parentReceiverID;

    //get pipe handle id
    parentSenderID = args[0];
    parentReceiverID = args[1];
                        
    //create streams
    var receiver = new AnonymousPipeClientStream (PipeDirection.In, parentSenderID);
    var sender = new AnonymousPipeClientStream (PipeDirection.Out, parentReceiverID);

    //read data
    int dataReceive = receiver.ReadByte();
    Console.WriteLine("Client receive: " + dataReceive.ToString());

    //write data
    byte dataSend = 24;
    sender.WriteByte(dataSend);
    Console.WriteLine("Client send: " + dataSend.ToString());           
}

 
Summary

Anonymous pipes offer an easy way to transfer data between two processes. Within this example only byte data was used. In the next article of this series I want to show you how you may transfer complex data classes by using serialization mechanisms.

Werbung
Dieser Beitrag wurde unter .NET, C# abgelegt und mit , , , verschlagwortet. Setze ein Lesezeichen auf den Permalink.

2 Antworten zu Inter-Process Communication with anonymous pipes, Part 01: transfer a byte stream

  1. Pingback: Inter-Process Communication with anonymous pipes, Part 02: transfer an object | coders corner

  2. Pingback: Inter-Process Communication with named pipes, Part 01: transfer a byte stream | coders corner

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit deinem WordPress.com-Konto. Abmelden /  Ändern )

Facebook-Foto

Du kommentierst mit deinem Facebook-Konto. Abmelden /  Ändern )

Verbinde mit %s