Named Pipes Full Duplex Communication Channel, Final Resolution

EDN Admin

Well-known member
Joined
Aug 7, 2010
Messages
12,794
Location
In the Machine
<p align=left><font face=Arial size=2>Hi there,</font> 
<p align=left><font face=Arial size=2>I am hereby posting a complete solution to Named Pipes Full Duplex Communication Channel realized within ONE process. The channel is used to send messages between the main form Form1 and secondary form FormOverSize which is modeless. It is a culmination of some agony, mostly unnecessary, over the subject that started a week ago. The same setup can and has been used for interprocesses communication (between app domains).</font>
<p align=left><font face=Arial size=2><a title="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2994048&SiteID=1 http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2994048&SiteID=1 http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2994048&SiteID=1 </font> 
<p align=left><font face=Arial size=2>The package includes 3 classes: PipeServer2 , PipeClent2 and SetControls . They are all static. SetControls is necessary because the purpose of the communication is to send messages to a textbox in the counterpart form where at TextChanged delegate it can be detected and processed.</font> 
<p align=left><font face=Arial size=2>The communication channel is very reliable and fast. I could not detect any delays. It is almost like seeing messages being printed out on Console.</font> 
<p align=left><font face=Arial size=2>Prototypes:</font>
<p align=left><font face=Arial size=2>Server: <a title="http://msdn2.microsoft.com/en-us/library/bb347348.aspx http://msdn2.microsoft.com/en-us/library/bb347348.aspx http://msdn2.microsoft.com/en-us/library/bb347348.aspx
Client: <a title="http://msdn2.microsoft.com/en-us/library/system.io.pipes.namedpipeclientstream.aspx http://msdn2.microsoft.com/en-us/library/system.io.pipes.namedpipeclientstream.aspx http://msdn2.microsoft.com/en-us/library/system.io.pipes.namedpipeclientstream.aspx </font>
<p align=left><font face=Arial size=2>Any suggestions in terms further improvement will be appreciated.</font>
<p align=left><font face=Arial size=2>// SERVER</font>
<p align=left>
<div class=codeseg>
<div class=codecontent>
<div class=codesniptitle><font style="width:100% Code Snippet</font>
<p align=left><font face=Arial size=2>using System;
using System.Text;
using System.IO.Pipes;</font>
<p align=left><font face=Arial size=2>namespace ComeAndGet
{
    public class PipeServer2
    {
        static bool readSetUp = false;
        static string PipeName = "CS3";
        static NamedPipeServerStream pipeServerStream2 = new NamedPipeServerStream ( PipeName, PipeDirection.InOut,
                      1, PipeTransmissionMode.Message, PipeOptions.Asynchronous );</font>
<p align=left><font face=Arial size=2>        public static void SendMessageToClient ( string msgInp )
        {
            if ( pipeServerStream2.IsConnected == false )
            {
                pipeServerStream2.WaitForConnection ( );
            }
            // sending messages
            UTF8Encoding encoding = new UTF8Encoding ( );
            byte[ ] bytes = encoding.GetBytes ( msgInp );
            pipeServerStream2.Write ( bytes, 0, bytes.Length );
            if ( readSetUp == false )
            {
                readSetUp = true;
                PipeServer2.GetMessageFromClient ( );
            }
        }                                               // SendMessageToClient </font>
<p align=left><font face=Arial size=2>        public static void GetMessageFromClient ( )
        {
            pipeServerStream2.ReadMode = PipeTransmissionMode.Message;
            Decoder decoder = Encoding.UTF8.GetDecoder ( );
            const int BufferSize = 4096;
            byte[ ] bytes = new byte[ BufferSize ];
            char[ ] chars = new char[ BufferSize ];
            int numBytes = 0;
            StringBuilder msg = new StringBuilder ( );
            do
            {
                msg.Length = 0;
                do
                {
                    numBytes = pipeServerStream2.Read ( bytes, 0, BufferSize );
                    if ( numBytes > 0 )
                    {
                        int numChars = decoder.GetCharCount ( bytes, 0, numBytes );
                        decoder.GetChars ( bytes, 0, numBytes, chars, 0, false );
                        msg.Append ( chars, 0, numChars );
                    }
                } while ( numBytes > 0 && !pipeServerStream2.IsMessageComplete );
                decoder.Reset ( );
                if ( numBytes > 0 )
                {
                    string message = msg.ToString ( );
                    Form1 form1 = new Form1 ( );
                    SetControls.SetControlText ( form1.textBox1, message );
                }
            } while ( numBytes != 0 );
        }
    }                                               // GetMessageFromClient
}                                          // namespace ComeAndGet</font>
<p align=left> <font face=Arial size=2>// CLIENT</font>
<p align=left>
<div class=codeseg>
<div class=codecontent>
<div class=codesniptitle><font style="width:100% Code Snippet</font>
<p align=left><font face=Arial size=2>using System;
using System.Text;
using System.IO.Pipes;
using System.Windows.Forms;</font>
<p align=left><font face=Arial size=2>namespace ComeAndGet
{
    class PipeClient2
    {
        static string PipeName = "CS3";
        const int BufferSize = 4096;
        static NamedPipeClientStream pipeClientStream2 = new NamedPipeClientStream ( ".",
                    PipeName, PipeDirection.InOut, PipeOptions.Asynchronous );
        static byte[ ] bytes = new byte[ BufferSize ];</font>
<p align=left><font face=Arial size=2>        public static void GetMessageFromServer (  )
        {
            if ( pipeClientStream2.IsConnected == false )
            {
                pipeClientStream2.Connect ( );
            }
            pipeClientStream2.ReadMode = PipeTransmissionMode.Message;
            Decoder decoder = Encoding.UTF8.GetDecoder ( );
            char[ ] chars = new char[ BufferSize ];
            int numBytes = 0;
            StringBuilder msg = new StringBuilder ( );
            do
            {
                msg.Length = 0;
                do
                {
                    numBytes = pipeClientStream2.Read ( bytes, 0, BufferSize );
                    if ( numBytes > 0 )
                    {
                        int numChars = decoder.GetCharCount ( bytes, 0, numBytes );
                        decoder.GetChars ( bytes, 0, numBytes, chars, 0, false );
                        msg.Append ( chars, 0, numChars );
                    }
                } while ( numBytes > 0 && !pipeClientStream2.IsMessageComplete );
                decoder.Reset ( );
                if ( numBytes > 0 )
                {
                    string message = msg.ToString ( );
                    FormOverSize forOver = new FormOverSize ( );
                    SetControls.SetControlText ( forOver.textBox1, message );
                }
            } while ( numBytes != 0 );
        }                                               // GetMessageFromServer</font>
<p align=left><font face=Arial size=2>        public static void SendMessageToServer ( string message )
        {
            if ( pipeClientStream2.IsConnected == false )
            {
                pipeClientStream2.Connect ( );
            }
            bytes.Initialize ( );
            for ( int jj = 0; jj < message.Length; jj++ )
            {
                bytes[ jj ] = (byte)message[ jj ];
            }
            pipeClientStream2.Write ( bytes, 0, message.Length );
        }                                               // SendMessageToServer
    }                                               // PipeClient2
}                                               // ComeAndGet</font>
<p align=left> <font face=Arial size=2>// SET CONTROLS</font>
<p align=left>
<div class=codeseg>
<div class=codecontent>
<div class=codesniptitle><font style="width:100% Code Snippet</font>
<p align=left><font face=Arial size=2>using System;
using System.Text;
using System.Windows.Forms;</font>
<p align=left><font face=Arial size=2>namespace ComeAndGet
{
    static class SetControls
    {
        public static void SetControlText ( System.Windows.Forms.Control clr, String text )
        {
            if ( clr.InvokeRequired )
            {
                clr.BeginInvoke ( ( MethodInvoker )delegate ( )
                {
                    SetControlText ( clr, text );
                } );
            }
            else
            {
                clr.Text = text;
            }
        }                                               // SetControlText
    }                                               // SetControls
}                                               // ComeAndGet
</font>
<p align=left> 
<p align=left> 

<p align=left><font face=Arial size=2> </font>

View the full article
 
Back
Top