PipeTransmissionMode.Message: ¿Cómo se distinguen las canalizaciones con nombre de.NET entre los mensajes?
named-pipes (2)
El modo de transmisión de tuberías es un concepto de sistema operativo Windows, no un concepto .NET. Si se crea una tubería en el modo Mensaje, cada escritura en la tubería por parte del remitente se trata como un mensaje separado. El receptor puede leer de la tubería:
- en modo Byte, cuando los datos se leen del conducto como una secuencia de bytes, ignorando por completo los límites implícitos del mensaje; o
- en modo Mensaje, cuando los datos se leen como una secuencia de mensajes, en el sentido de que cualquier lectura solo recibirá bytes relacionados con un solo mensaje, y la API nativa devolverá un código de error especial para indicar si hay más bytes para ser recibido por el mismo mensaje.
El ajuste .NET de esta funcionalidad, tal como apareció en el espacio de nombres System.IO.Pipes
, sigue bastante de cerca el modelo nativo subyacente:
- los límites de mensajes todavía están determinados por el patrón de llamadas realizadas por el emisor a
PipeStream.Write()
oPipeStream.WriteByte()
: los datos escritos en cada llamada se tratan como un mensaje distinto; - el receptor puede establecer
ReadMode
enPipeTransmissionMode.Message
, y luego cada llamada aPipeStream.Read()
oPipeStream.ReadByte()
leerá el siguiente fragmento de datos del mensaje actual, hasta que el valor dePipeStream.IsMessageComplete
cambie atrue
, indicando que todos los bytes para ese mensaje han sido leídos
Todas las lecturas y escrituras se realizan en términos de bytes o matrices de bytes. Puede enviar los bytes que desee a través de una tubería. El modo de transmisión no tiene nada que ver con esto.
Entonces, sí, puede enviar un objeto serializado como un mensaje, siempre que escriba todos los bytes de su representación serializada en la tubería en una sola llamada a PipeStream.Write()
.
¿Alguien puede aclarar el significado de PipeTransmissionMode.Message
en .NET?
¿Cómo distingue .NET un mensaje pasado por el conducto de otro?
- ¿Puedo serializar un objeto usando un
BinaryFormatter
y luego pasarlo a través de la tubería como un mensaje? - ¿O solo se permiten mensajes de cadena cuando la tubería está en modo
PipeTransmissionMode.Message
?
Me tomó un tiempo encontrar el pequeño detalle importante que necesita para crear tanto el servidor como el cliente en el modo PipeDirection.InOut
:
Puede ser extraño, pero por alguna razón, se debe crear un PipeDirection
con un parámetro InOut
de InOut
para que PipeTransmissionMode.Message
funcione. No solo esto no se documenta directamente, sino que la forma en que se informa el error es completamente contra-intuitiva, y parece no tener nada que ver con el modo de TransmissionMode
la tubería.
De lo contrario, obtendrá la excepción:
Intentando conectar a la tubería ... System.UnauthorizedAccessException:
El acceso a la ruta es denegado.
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)