2010-12-22 8 views
36

¿Alguien puede aclarar el significado de PipeTransmissionMode.Message en .NET?PipeTransmissionMode.Message: ¿Cómo se distingue entre los mensajes de las vías nombradas .NET?

¿Cómo distingue .NET un mensaje que se transmite 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?

Respuesta

47

El modo de transmisión de tubería 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 desde el tubo o bien:

  • en modo Byte, cuando los datos se leen desde la tubería como un flujo de bytes, ignorando por completo los límites mensaje implícito; 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 devuelve un código de error especial para indicar si hay otros bytes que se recibirán para ese mismo mensaje.

La envoltura .NET de esta funcionalidad, como surgido en el espacio de nombres System.IO.Pipes, sigue el modelo nativo subyacente bastante de cerca:

  • mensaje límites siguen siendo determinada por el patrón de las llamadas realizadas por el remitente a PipeStream.Write() o PipeStream.WriteByte() - los datos escritos en cada llamada se tratan como un mensaje distinto ;
  • el receptor puede establecer ReadMode a PipeTransmissionMode.Message, y después de cada llamada a PipeStream.Read() o PipeStream.ReadByte() leerá el siguiente fragmento de los datos del mensaje actual, hasta que el valor de PipeStream.IsMessageComplete cambios a true, lo que indica que todos los bytes para que el mensaje tienen leído

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.

Por lo tanto, sí, puede enviar un objeto serializado como un mensaje, siempre que escriba todos los bytes de su representación serializada en una sola llamada al PipeStream.Write().

4

Me tomó un tiempo para encontrar el pequeño detalle importante que se necesita para crear el servidor y el cliente en PipeDirection.InOut modo:

Puede ser extraño, pero por alguna razón, un NamedPipeServerStream deben crearse con un PipeDirection parámetro de InOut para que PipeTransmissionMode.Message funcione. No solo esto no está documentado directamente, sino que la forma en que se informa el error es completamente contra-intuitiva, y parece no tener nada que ver con el TransmissionMode de la tubería.

De lo contrario obtendrá la excepción:

Si intenta conectarse a la tubería ... System.UnauthorizedAccessException:

acceso a la ruta 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) 
+3

He publicado una explicación completa de este problema y una solución mejor aquí: http://stackoverflow.com/q/32739224/3418322 –

Cuestiones relacionadas