Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

duplex operation between two processes using named pipes in c#

I am trying to use named pipes to communicate between a server and a client process on the same machine. server sends a message to client, client does something with it and returns a result, and server is supposed to get the result.

here is the code for server:

using System;
using System.IO;
using System.IO.Pipes;

class PipeServer
{
    static void Main()
    {
        using (NamedPipeServerStream pipeServer =
            new NamedPipeServerStream("testpipe", PipeDirection.InOut))
        {
            Console.WriteLine("NamedPipeServerStream object created.");

            // Wait for a client to connect
            Console.Write("Waiting for client connection...");
            pipeServer.WaitForConnection();

            Console.WriteLine("Client connected.");
            try
            {
                // Read user input and send that to the client process.
                using (StreamWriter sw = new StreamWriter(pipeServer))
                {
                    sw.AutoFlush = true;
                    Console.Write("Enter text: ");
                    sw.WriteLine(Console.ReadLine());
                }

                pipeServer.WaitForPipeDrain();

                using (StreamReader sr = new StreamReader(pipeServer))
                {
                    // Display the read text to the console 
                    string temp;

                    // Wait for result from the client. 
                    while ((temp = sr.ReadLine()) != null)
                    {
                        Console.WriteLine("[CLIENT] Echo: " + temp);
                    }
                }

            }
            // Catch the IOException that is raised if the pipe is 
            // broken or disconnected.
            catch (IOException e)
            {
                Console.WriteLine("ERROR: {0}", e.Message);
            }
        }
    }
}

and here is the code for client:

using System;
using System.IO;
using System.IO.Pipes;

class PipeClient
{
    static void Main(string[] args)
    {
        using (NamedPipeClientStream pipeClient =
            new NamedPipeClientStream(".", "testpipe", PipeDirection.InOut))
        {

            // Connect to the pipe or wait until the pipe is available.
            Console.Write("Attempting to connect to pipe...");
            pipeClient.Connect();

            Console.WriteLine("Connected to pipe.");
            Console.WriteLine("There are currently {0} pipe server instances open.",
               pipeClient.NumberOfServerInstances);
            using (StreamReader sr = new StreamReader(pipeClient))
            {
                // Display the read text to the console
                string temp;
                while ((temp = sr.ReadLine()) != null)
                {
                    Console.WriteLine("Received from server: {0}", temp);
                }
            }


            // send the "result" back to the Parent process.
            using (StreamWriter sw = new StreamWriter(pipeClient))
            {
                sw.AutoFlush = true;
                sw.WriteLine("Result");
            }

            pipeClient.WaitForPipeDrain();

        }
        Console.Write("Press Enter to continue...");
        Console.ReadLine();
    }
}

But in the server code, on line pipeServer.WaitForPipeDrain(); I get an ObjectDisposedException and it says "cannot access a closed pipe."

I also get the same error in the client code on when setting sw.AutoFlush to true.

Basically I couldn't find an example of duplex named pipe in c#. I either need that, or an example of anonynous pipe, with two pipes one for reading and one for writting between a parent and a child process.

Thanks in Advance.

like image 429
jambodev Avatar asked Feb 12 '13 13:02

jambodev


People also ask

Is named pipe duplex?

A named pipe is a one-way or duplex pipe that provides communication between the pipe server and some pipe clients. A pipe is a section of memory that is used for interprocess communication.

Can a process create two named pipes for communication with two different processes?

The answer is YES. Named pipe is meant for communication between two or more unrelated processes and can also have bi-directional communication.

Are named pipes bidirectional?

Named pipes are strictly unidirectional, even on systems where anonymous pipes are bidirectional (full-duplex).

Can there be two way communication over a single pipe?

Yes it can, I've done that before. I had a parent and child send each other different messages using the same 2 pipes and receive them correctly. Just make sure you're always reading from the first file descriptor and writing to the second.


1 Answers

The Problem is the using block of the StreamWriter, which will close the underlying Stream (which is your pipe here). If you don't use that block it should work.

You could do the following:

using (var pipeServer = new NamedPipeServerStream("testpipe", PipeDirection.InOut))
using (var streamReader = new StreamReader(pipeServer))
using (var streamWriter = new StreamWriter(pipeServer))
{
   // ... Your code ..
}

As Johannes Egger pointed out, the StreamWriter flushes the stream on Dispose(), so the StreamWriter should be disposed first and thus be the inner-most object to dispose.

like image 117
TGlatzer Avatar answered Nov 03 '22 00:11

TGlatzer