Interprocess Communication: Part 3

December 10, 2014

Blog | Development | Interprocess Communication: Part 3
Interprocess Communication: Part 3

Welcome to part three in the IPC series! Today, we’ll be taking a look at Pipes.

Pipes are another mechanism by which processes can communicate with each other. When using a pipe, similar to other communication mechanisms shown, one side is responsible for reading and one side is responsible for writing.

Picture a faucet in your home. When you turn the faucet on, you expect water to come gushing out. But when the faucet is off, you equally expect that the water will simply sit and wait in the pipe until you’re ready for it.


Digital pipes are very similar. Data can be placed into the pipe and will queue up behind each piece of information you have stored until the receiving end opens the floodgates to start consuming the data. So… what does a Pipe provide that something like a Socket doesn’t? The ability to write to it without anybody reading from it. That is, the application placing data in the pipe can do so freely and the data will be queued in the pipe as expected, even without a consuming application on the other end. Once a consumer connects to the pipe, the data will begin flooding out of the pipe on the other end until it is empty. Because software projects each have their own own quirks, requirements, and pitfalls, Pipes may be a necessary evil to accomplish a certain task. Ultimately, it’s for the devs working on your project to decide.

Let’s take a look at how a Pipe-based communication implementation is done.

using (var pipeServer = new NamedPipeServerStream(PipeName))
{
    Console.WriteLine("Pipe created. Awaiting connection...");
    pipeServer.WaitForConnection();

    var pipeStream = new PipeStringStream(pipeServer);
    Console.WriteLine("Awaiting messages...");
    
    var doLoop = true;
    do
    {
        var data = pipeStream.Read();
        Console.WriteLine("Message Received : {0}", data);
        if (data == "exit")
        {
            doLoop = false;
        }

    } while (doLoop);
}

...

using (var pipeClient = new NamedPipeClientStream(PipeName))
{
    Console.WriteLine("Connecting to {0}...", ReaderName);
    try
    {
        pipeClient.Connect();
    }
    catch
    {
        return;
    }

    var pipeStream = new PipeStringStream(pipeClient);

    var doLoop = true;
    do
    {
        Console.Write("Message to send ("exit" to quit): ");
        var line = Console.ReadLine();
        pipeStream.Write(line);
        doLoop = (line != "exit");
    } while (doLoop);
}

Once again, this example is simply showing simple string messages being sent across the pipe. Since the pipe is simply transmitting bytes of information, any data can be sent as long as both sides “speak” the same language (at least, where the language, in this case, is the pattern to inform the receiving end just how much data is flowing through).

Pipes, like other communication mechanisms, have been greatly abstracted from the user by the bees at Microsoft responsible for the .Net framework. However, subtle differences shine compared to the other interprocess communications.


The full source for the above example can be found here.

Stay tuned next time for the continuation of the IPC Series, where we’ll be looking at Semaphores, Mutexes, and Wait Handles!

Phil Azzi, Developer, GeekHive

Phil Azzi

Technical Lead
Tags
  • Patterns & Practices
  • Tutorial

Recent Work

Check out what else we've been working on