Skip to content

Communicating between Processes using Pipes in C#

November 23, 2012

Hi all,

Recently had an interesting lab session on using pipes as a method of communication between processes.

Pipes started off life on Unix systems as a way of transferring data between processes on the same machine. Pipes are now a method of IPC (Inter Process Communication).

Below I will show a very simple example of how to implement named pipes into a C# application.
First of create a console application in Visual Studio.
Then add a public method called ThreadStartServer to the program class generated by the IDE. The methods return type is void. Also create a  public method again with no return type called ThreadStartClient. The client method takes one parameter called obj of type object
Inside the ThreadStartServer method paste the following code.


//Create a named pipe using the current process ID of this application
 using (NamedPipeServerStream pipeStream = new NamedPipeServerStream("PipeTo" + Process.GetCurrentProcess().Id.ToString()))
 {
 Console.WriteLine("[Server] Pipe Created, the current process ID is {0}", Process.GetCurrentProcess().Id.ToString());

//wait for a connection from another process
 pipeStream.WaitForConnection();
 Console.WriteLine("[Server] Pipe connection established");

using (StreamReader sr = new StreamReader(pipeStream))
 {
 string message;
 //wait for message to arrive from the pipe, when message arrive print date/time and the message to the console.
 while((message = sr.ReadLine()) != null)
 {
 Console.WriteLine("{0}: {1}", DateTime.Now, message);
 }
 }
 }
 Console.WriteLine("Connection lost");

Inside the ThreadStartClient method insert the following code

//Ensure that we only start the client after the server has created the pipe
 ManualResetEvent SyncClientServer = (ManualResetEvent) obj;
 Console.WriteLine("Please enter the process ID to connect to");
 string processIDToCall = Console.ReadLine();

//Only continue after the server is created
 using (NamedPipeClientStream pipeStream = new NamedPipeClientStream("PipeTo" + processIDToCall))
 {
 //The connect function will indefinately wait for the pipe to become available
 //If that is not acceptable specify a maximum waiting time (ms)
 pipeStream.Connect();

Console.WriteLine("[Client] Pipe Connection established");
 using (StreamWriter sw = new StreamWriter(pipeStream))
 {
 sw.AutoFlush = true;
 string message;
 Console.WriteLine("Please type a message and press [ENTER], or type 'quit' to exit the program");
 while((message = Console.ReadLine()) != null)
 {
 if (message == "quit")
 break;
 sw.WriteLine(message);
 }
 }
 }

Assuming your main class is called program, add the following code to the main method


Program reciever = new Program();
 Program sender = new Program();

Thread RecieverThread = new Thread(reciever.ThreadStartServer);
 Thread SenderThread = new Thread(sender.ThreadStartClient);

RecieverThread.Start();
 SenderThread.Start();

You can then run the application twice, once inside the debugger and visual studio and a second instance by navigating and executing the file created by the compiler. Following the instructions from the console will provide a basic messaging client between two processes on the same machine.

This application has shown how to create a unique named pipe which only has a single direction of travel. The pipe can send any message or object down the pipe to the interconnected process. In order to create bi-directional communication we have created another pipe going in the opposite direction. The method of joining the processes to each end of the pipes is straightforward. Careful management needs to be executed to provide a robust application when dealing with code that you are asking to wait for a message until it gets one. Luckily in this method if a pipes connection is lost then the application stops the waiting for a message without causing an exception. If this mechanism was not in place the application would have to be force-ably terminated to stop it waiting for a message from a no longer existent pipe.

Advertisements

From → Uncategorized

2 Comments
  1. Michael Baker permalink

    Thanks for the example, very simple and easy to follow.
    There is a small mistake in ThreadStartSever the string format index should be 0 not 1.

    • Hi Michael,

      Yes you are quite right, I’m not even too sure how that happened. Must have done something in error between testing and writing the blog post.

      Many thanks for pointing this out.

      Andrew

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: