Asked by:
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.aspxAny suggestions in terms further improvement will be appreciated.
// SERVER
Code Snippetusing 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 ( );
}
} // SendMessageToClientpublic 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 Snippetusing 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 );
} // GetMessageFromServerpublic 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 Snippetusing 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- Edited by AlexBB - Vista Ult64 SqlSer64 WinSer64 Saturday, June 21, 2008 8:39 PM beautification:)
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.comSunday, 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- Edited by AlexBB - Vista Ult64 SqlSer64 WinSer64 Sunday, June 29, 2008 11:16 PM corection
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 7, 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
MikeTuesday, February 1, 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 -
Hi Benjamin,
The link to your blog doesn't work.
(And unlike AlexBB, I don't suffer from .zip file aversion derangement syndrome.)
If you still have that program available I'd be interested in seeing it.
Rennie
A bit later ...
Never mind, I think I've found it (twice, in fact):http://www.benday.com/2008/06/22/playing-with-nets-named-pipe-streams-with-net-to-net-and-win32-to-net-samples/
http://www.benday.com/2008/06/22/playing-with-nets-named-pipe-streams-with-net-to-net-and-win32-to-net-samples-2/
Thanks for posting it.
- Edited by RennieP Wednesday, March 25, 2015 10:45 AM
Wednesday, March 25, 2015 9:56 AM -
Hi Alex, I know this is ancient history but the link to the project is broken :-)
Looking at all sorts of solutions to interprocess communication in C# (rather than C++) and this link came up :-)
mmacneill123 (MCP)
Friday, March 27, 2015 11:14 AM