PipeTransmissionMode.Message:.NET命名pipe道如何区分消息?

有人可以澄清的PipeTransmissionMode.Message在.NET中的含义?

.NET如何区分通过pipe道传递的另一条消息?

  • 我可以序列化使用BinaryFormatter对象,然后通过pipe道作为消息?
  • 或者当pipe道处于PipeTransmissionMode.Message模式时,只允许string消息?

pipe道传输模式是Windows操作系统的概念,而不是.NET概念。 如果在消息模式下创buildpipe道,则发件人对pipe道的每个写入都将被视为单独的消息。 接收器可以从pipe道读取:

  • 在字节模式下,当数据从pipe道读取为字节stream时,完全忽略隐含的消息边界; 要么
  • 在消息模式下,当数据以消息stream的forms读取时,任何读取都只能接收与单个消息相关的字节,而本地API返回一个特殊的错误代码来指示是否还有字节收到相同的消息。

正如System.IO.Pipes命名空间中所展示的,.NETfunction的封装紧密地遵循底层本机模型:

  • 消息边界仍然由发送者对PipeStream.Write()PipeStream.WriteByte()所做的调用模式决定 – 写入每个调用中的数据被视为不同的消息;
  • 接收方可以将ReadMode设置为PipeTransmissionMode.Message ,然后对PipeStream.Read()PipeStream.ReadByte()每次调用都将读取当前消息中的下一个数据块,直到PipeStream.IsMessageComplete的值更改为true ,该消息的所有字节已被读取

所有的读写操作都是以字节或字节数组的forms完成的。 你可以发送任何你喜欢的pipe道字节。 TransmissionMode对此没有影响。

所以,是的,您可以发送一个序列化的对象作为消息,只要您一次性调用PipeStream.Write() ,就可以将其序列化表示的所有字节写入pipe道。

花了我一段时间来find你需要在PipeDirection.InOut模式下创build服务器和客户端的小重要细节:

这可能很奇怪,但出于某种原因,必须使用PipeDirection参数创buildNamedPipeServerStream ,以使PipeTransmissionMode.Message正常工作。 这不仅没有直接logging,而且报告错误的方式完全是违反直觉的,似乎与pipe道的TransmissionMode无关。

否则,你会得到exception:

试图连接到pipe道… System.UnauthorizedAccessException:

访问path被拒绝。

  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)