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

  • Hey AlexBB,

    It looks like we're trying to do similar but different stuff.  Thanks for posting your code.

    Here's a link to a blog post I just wrote describing my process and the headaches.  There's also a link to a sample app that does named pipe communications from .NET-to-.NET and Win32-to-.NET.

    http://blog.benday.com/archive/2008/06/22/23182.aspx

    -Ben
    Benjamin Day - Microsoft MVP for C# -- http://blog.benday.com
    Sunday, June 22, 2008 2:49 PM
  • Benjamin Day said:

    Hey AlexBB,

    It looks like we're trying to do similar but different stuff.  Thanks for posting your code.

    Here's a link to a blog post I just wrote describing my process and the headaches.  There's also a link to a sample app that does named pipe communications from .NET-to-.NET and Win32-to-.NET.

    http://blog.benday.com/archive/2008/06/22/23182.aspx

    -Ben


    Benjamin Day - Microsoft MVP for C# -- http://blog.benday.com


    I am not downloading any zip files. Period. Unless it is MS of course or a reputable manufacturer like Intel or DELL.

    AlexB
    Sunday, June 22, 2008 4:51 PM
  • @Benjamin,

    I downloaded your code and that was excellent. I was exactly looking for that.

    Thanks,

    James

    Wednesday, April 07, 2010 4:09 AM
  • I just ran across this post of yours - it looks to be very helpful.

    But, I'm not familiar with this forum. Where can I find the solution you posted?

    Sorry for asking such a dumb question.

    -Mike

     


    Mike
    Tuesday, February 01, 2011 6:53 PM
  • I am not downloading any zip files. Period. Unless it is MS of course or a reputable manufacturer like Intel or DELL.

    This is absurd!  You're lost!

    Tuesday, September 10, 2013 6:18 PM