PipeTransmissionMode.Message: Как именованные каналы .NET различают сообщения? - PullRequest
40 голосов
/ 23 декабря 2010

Может кто-нибудь прояснить значение PipeTransmissionMode.Message в .NET?

Как .NET различает одно сообщение, переданное по каналу, от другого?

  • Могу ли я сериализовать объект, используя BinaryFormatter, а затем передать его через канал в качестве сообщения?
  • Или разрешены только строковые сообщения, когда канал находится в режиме PipeTransmissionMode.Message?

Ответы [ 2 ]

53 голосов
/ 23 декабря 2010

Режим конвейерной передачи - это концепция операционной системы Windows, а не концепция .NET.Если канал создается в режиме сообщений, каждая запись отправителя трактуется в канал как отдельное сообщение.Получатель может читать из канала либо:

  • в байтовом режиме, когда данные считываются из канала в виде потока байтов, полностью игнорируя неявные границы сообщения;или
  • в режиме сообщений, когда данные читаются как поток сообщений, в том смысле, что при любом чтении будут приниматься только байты, относящиеся к одному сообщению, а собственный код ошибки возвращается собственным API для указанияесли для этого же сообщения будут получены дополнительные байты.

. Обтекание этой функциональности .NET, как показано в пространстве имен System.IO.Pipes, довольно близко следует базовой модели:

  • границы сообщения по-прежнему определяются шаблоном вызовов, сделанных отправителем на PipeStream.Write() или PipeStream.WriteByte() - данные, записанные в каждом вызове, рассматриваются как отдельное сообщение;
  • получательможно установить ReadMode на PipeTransmissionMode.Message, а затем каждый вызов PipeStream.Read() или PipeStream.ReadByte() будет считывать следующий фрагмент данных из текущего сообщения, пока значение PipeStream.IsMessageComplete не изменится на true, указывая, что всебайты для этого сообщения были прочитаны

Все операции чтения и записи выполняются в виде байтов или массивов байтов.Вы можете отправить любые байты, которые вам нравятся, по трубе.TransmissionMode не имеет никакого отношения к этому.

Итак, да, вы можете отправить сериализованный объект в виде сообщения, если вы записываете все байты его сериализованного представления в канал за один вызов PipeStream.Write().

6 голосов
/ 20 февраля 2015

Мне потребовалось некоторое время, чтобы найти маленькие важные детали, необходимые для создания сервера и клиента в режиме PipeDirection.InOut:

Это может быть странно, но по какой-то причине для работы PipeTransmissionMode.Message необходимо создать NamedPipeServerStream с параметром PipeDirection, равным InOut. Мало того, что это непосредственно не задокументировано, но и способ сообщения об ошибке совершенно нелогичен, и, похоже, не имеет ничего общего с 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...