none
Named Pipes Full Duplex Communication Channel, Final Resolution

    General discussion

  • Hi there, 

    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).

    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2994048&SiteID=1 

    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. 

    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. 

    Prototypes:

    Server: http://msdn2.microsoft.com/en-us/library/bb347348.aspx
    Client: http://msdn2.microsoft.com/en-us/library/system.io.pipes.namedpipeclientstream.aspx

    Any suggestions in terms further improvement will be appreciated.

    // SERVER

    Code Snippet

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

    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 );

            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

            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

     // CLIENT

    Code Snippet

    using System;
    using System.Text;
    using System.IO.Pipes;
    using System.Windows.Forms;

    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 ];

            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

            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

     // SET CONTROLS

    Code Snippet

    using System;
    using System.Text;
    using System.Windows.Forms;

    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

     

     

    Wednesday, March 19, 2008 1:37 PM

All replies