<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Martijn's C# Programming Blog &#187; named pipes</title>
	<atom:link href="http://www.dijksterhuis.org/tag/named-pipes/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.dijksterhuis.org</link>
	<description>Information, news about programming in C#</description>
	<lastBuildDate>Fri, 07 Aug 2009 21:26:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>Using Named Pipes in C# / Windows</title>
		<link>http://www.dijksterhuis.org/using-named-pipes-in-c-windows/</link>
		<comments>http://www.dijksterhuis.org/using-named-pipes-in-c-windows/#comments</comments>
		<pubDate>Thu, 20 Nov 2008 09:30:57 +0000</pubDate>
		<dc:creator>Martijn</dc:creator>
				<category><![CDATA[Beginner]]></category>
		<category><![CDATA[Learn C#]]></category>
		<category><![CDATA[named pipes]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://www.dijksterhuis.org/?p=221</guid>
		<description><![CDATA[Communication between different threads in a process is trivial as they share the same objects in memory. But what if you would like to communicate with a different process (program) on the same computer? You could open a TCP/IP port to share data but the added overhead of this would slow down your program if [...]<p>This is a post from <a href="http://www.dijksterhuis.org">Martijn's C# Coding Blog</a>. </p>
]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.dijksterhuis.org/wp-content/uploads/2008/11/pipes.jpg" alt="" title="Using named pipes in C# / Windows" width="500" height="279" class="alignnone size-full wp-image-224" /></p>
<p><em>Communication between different threads in a process is trivial as they share the same objects in memory. But what if you would like to communicate with a different process (program) on the same computer? You could open a TCP/IP port to share data but the added overhead of this would slow down your program if you send a lot of data.</em></p>
<p><span id="more-221"></span></p>
<p>Traditionally you would use a pipe: a pseudo file that allows one process to write and another to process to read. This is very similar to reading and writing from a file. This is more efficient as the information is passed straight through the kernel between processes and avoids the network stack overhead.</p>
<p>There are two kinds of pipes:</p>
<p><strong>Anonymous pipes</strong></p>
<p>These are typically used for communication between a parent and child process. As the pipe does not have a name we need to be able to pass a handle to it from one process to another. Typically this is done by passing this handle as an argument when starting the child process.</p>
<p><strong>Named pipes</strong></p>
<p>Named pipes are more generally useful. If a process is aware of the name of a pipe it can connect to it. There is no need for an immediate parent / child relationship. As long as the parent process makes the pipe available, other processes can connect to it.</p>
<p><strong>Pipes and Windows</strong></p>
<p>The Windows OS offers a solid set of named and unnamed pipe function calls in the kernel. But for some reason Microsoft didn&#8217;t actually include pipes in C# until .NET 3.5. The support for pipes is now included in the <em>System.IO.Pipes</em> class. In the intervening years enterprising programmers created their own set of non-portable bindings to the Kernel32 calls and on Linux the Mono teambuild their own set of calls to support Unix sockets in the <em>Mono.Unix.UnixPipes</em> class.</p>
<p>As a result there is currently no portable way to implement pipes under both .NET/Windows and Linux/Mono. In the following example I show you how to create a named pipe for Windows.</p>
<p>Because of the nature of a named pipe &#8212; we are going to need two programs: one that establishes the pipe, and another one that reads from the pipe.</p>
<p><strong>Example: Named Pipes in Visual C# / .NET 3.5</strong></p>
<p>With the introduction of <em>System.IO.Pipes</em> in .NET 3.5 creating and connecting to a pipe has become very straightforward.</p>
<ul>
<li>NamedPipeServerStream creates a pipe
<li>NamedPipeClientStream connects to an existing pipe
</ul>
<p>In the below example we simulate the communication between two processes by creating two threads instead. This makes debugging this example easier but in reality this could also have been an example of communication between two separate processes on the same computer.</p>
<p>We also make implicity use of the fact that <em>NamedPipeClientStream.Connect()</em> will wait for the pipe to be created if it can&#8217;t find it on its first try.  If this is not acceptable it is also possible to call <em>Connect</em> with a time-out in milliseconds &#8212; if the pipe is not created in the time specified the function will fail. </p>
<pre class="brush: c#">
using System;
using System.IO;
using System.IO.Pipes;
using System.Threading;

namespace PipeApplication1
{
    class ProgramPipeTest
    {

        public void ThreadStartServer()
        {
            // Create a name pipe
            using (NamedPipeServerStream pipeStream = new NamedPipeServerStream(&quot;mytestpipe&quot;))
            {
                Console.WriteLine(&quot;[Server] Pipe created {0}&quot;, pipeStream.GetHashCode());

                // Wait for a connection
                pipeStream.WaitForConnection();
                Console.WriteLine(&quot;[Server] Pipe connection established&quot;);

                using (StreamReader sr = new StreamReader(pipeStream))
                {
                    string temp;
                    // We read a line from the pipe and print it together with the current time
                    while ((temp = sr.ReadLine()) != null)
                    {
                        Console.WriteLine(&quot;{0}: {1}&quot;, DateTime.Now, temp);
                    }
                }
            }

            Console.WriteLine(&quot;Connection lost&quot;);
        }

        public void ThreadStartClient(object obj)
        {
            // Ensure that we only start the client after the server has created the pipe
            ManualResetEvent SyncClientServer = (ManualResetEvent)obj;

            // Only continue after the server was created -- otherwise we just fail badly
            // SyncClientServer.WaitOne();

            using (NamedPipeClientStream pipeStream = new NamedPipeClientStream(&quot;mytestpipe&quot;))
            {
                // The connect function will indefinately wait for the pipe to become available
                // If that is not acceptable specify a maximum waiting time (in ms)
                pipeStream.Connect();

                Console.WriteLine(&quot;[Client] Pipe connection established&quot;);
                using (StreamWriter sw = new StreamWriter(pipeStream))
                {
                    sw.AutoFlush = true;
                    string temp;
                    Console.WriteLine(&quot;Please type a message and press [Enter], or type &#039;quit&#039; to exit the program&quot;);
                    while ((temp = Console.ReadLine()) != null)
                    {
                        if (temp == &quot;quit&quot;) break;
                        sw.WriteLine(temp);
                    }
                }
            }
        }

        static void Main(string[] args)
        {

            // To simplify debugging we are going to create just one process, and have two tasks
            // talk to each other. (Which is a bit like me sending an e-mail to my co-workers)

            ProgramPipeTest Server = new ProgramPipeTest();
            ProgramPipeTest Client = new ProgramPipeTest();

            Thread ServerThread = new Thread( Server.ThreadStartServer );
            Thread ClientThread = new Thread(Client.ThreadStartClient);

            ServerThread.Start();
            ClientThread.Start();
        }
    }
}
</pre>
<p><small>Image credit: <a rel="nofollow" href="http://www.flickr.com/photos/28481088@N00/">TanakaWho</a></small></p>
<p>This is a post from <a href="http://www.dijksterhuis.org">Martijn's C# Coding Blog</a>. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.dijksterhuis.org/using-named-pipes-in-c-windows/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

