Can somebody clarify the meaning of PipeTransmissionMode.Message in .NET?
How does .NET distinguish one message passed through the pipe from another?
The pipe transmission mode is a Windows operating system concept, not a .NET concept. If a pipe is created in Message mode, each write to the pipe by the sender is treated as a separate message. The receiver can read from the pipe either:
The .NET wrapping of this functionality, as surfaced in the System.IO.Pipes
namespace, follows the underlying native model fairly closely:
PipeStream.Write()
or
PipeStream.WriteByte()
- the data
written in each call is treated as a distinct
message;ReadMode
to
PipeTransmissionMode.Message
, and then every call to PipeStream.Read()
or PipeStream.ReadByte()
will read the next chunk of data from the current message, until the value of PipeStream.IsMessageComplete
changes to true
, indicating that all the bytes for that message have been readAll reads and writes are done in terms of bytes or arrays of bytes. You can send whatever bytes you like down a pipe. The TransmissionMode has no bearing on this.
So, yes, you can send a serialized object as a message, provided you write all the bytes of its serialized representation to the pipe in a single call to PipeStream.Write()
.
Took me a while to find the little important detail that you need to create both the server and client in PipeDirection.InOut
mode:
It may be odd, but for some reason, a NamedPipeServerStream
must be created with a PipeDirection
parameter of InOut
in order for PipeTransmissionMode.Message
to work. Not only is this not directly documented, but the way the error is reported is completely counter-intuitive, and appears to have nothing to do with the pipe's TransmissionMode
.
Otherwise you'll get the exception:
Attempting to connect to pipe...System.UnauthorizedAccessException:
Access to the path is denied.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) at System.IO.Pipes.PipeStream.WinIOError(Int32 errorCode) at System.IO.Pipes.PipeStream.set_ReadMode(PipeTransmissionMode value)