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

Art*_*sky 42 .net named-pipes

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

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

  • 我可以使用a序列化对象BinaryFormatter,然后将其作为消息传递给管道吗?
  • 或者只是在管道处于PipeTransmissionMode.Message模式时允许的字符串消息?

Chr*_*son 54

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

  • 在字节模式下,当数据作为字节流从管道中读取时,完全忽略隐含的消息边界; 要么
  • 在消息模式下,当数据作为消息流读取时,在任何读取只接收与单个消息相关的字节的意义上,本机API返回特殊错误代码以指示是否还有其他字节收到同样的消息.

这个功能的.NET包装,如System.IO.Pipes命名空间中所示,非常接近底层本机模型:

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

所有读取和写入都是按字节或字节数组完成的.您可以在管道中发送您喜欢的任何字节.TransmissionMode与此无关.

所以,是的,您可以将序列化对象作为消息发送,前提是您在一次调用中将其序列化表示的所有字节写入管道PipeStream.Write().


Thy*_*ine 5

花了一些时间来找到在PipeDirection.InOut模式下创建服务器和客户端所需的重要细节:

这可能是奇怪,但出于某种原因,NamedPipeServerStream必须以创建PipeDirection的参数InOut,以便PipeTransmissionMode.Message工作.这不仅没有直接记录,而且报告错误的方式完全违反直觉,并且似乎与管道无关TransmissionMode.

否则你会得到例外:

试图连接到管道... System.UnauthorizedAccessException:

拒绝访问该路径.

   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)
Run Code Online (Sandbox Code Playgroud)

  • 我已经在这里发布了这个问题的完整解释和更好的解决方案:http://stackoverflow.com/q/32739224/3418322 (3认同)