2015-07-01 3 views
1

Существуют ли особые требования при использовании Protobuf-net для отправки двоичного массива? У меня есть класс сообщений, который оборачивает некоторые двоичные данные:Отправка двоичных данных Protobuf-net

[ProtoContract] 
public class BitmapPackage : BaseMessage 
{ 
    [ProtoMember(1)] 
    public byte[] BitmapData; 
} 

При попытке десериализации сообщения я поймать исключение брошенного Protobuf-сеть:

16: 52: 59.902: (007): [Ошибка] Внутреннее исключение в StartReceiveLoop(): Сообщение: Попытка прочитать за конец потока. Трассировка стека: в ProtoBuf.ProtoReader.Ensure (Int32 count, Boolean strict) в c: \ Dev \ protobuf-net \ protobuf-net \ ProtoReader.cs: строка 257 на ProtoBuf.ProtoReader.AppendBytes (значение байта [], считыватель ProtoReader) в c: \ Dev \ protobuf-net \ protobuf-net \ ProtoReader.cs: строка 921 на proto_4 (О bject, ProtoReader) на ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read (значение объекта, источник ProtoReader) в c: \ Dev \ protobuf-net \ protobuf-net \ Serializers \ CompiledSerializer.cs: строка 57 at ProtoBuf.Meta.RuntimeTypeModel.Deserialize (ключ Int32, значение Object, источник ProtoReader) в c: \ Dev \ protobuf-net \ protobuf-net \ Meta \ RuntimeTypeModel.cs: строка 775 на ProtoBuf.Meta.TypeModel.DeserializeCore (ProtoReader читатель, тип типа, значение объекта, логическое значение noAutoCreate) в c: \ Dev \ protobuf-net \ protobuf-net \ Meta \ TypeModel.cs: строка 700 на ProtoBuf.Meta.TypeModel.Deserialize (источник потока, значение объекта, тип type, SerializationContext context) в c: \ Dev \ protobuf-net \ protobuf-net \ Meta \ TypeModel.cs: строка 588 на ProtoBuf.Serializer.Deserialize [T] (источник потока) в c: \ Dev \ protobuf-net \ protobuf-net \ Serializer.cs: строка 7 7

Это происходит только и всегда, когда я отправляю одно конкретное растровое изображение. Итак, мой вопрос в том, должен ли я как-то «сбежать» от двоичных данных, прежде чем десериализировать его с помощью protobuf-net?

UPDATE: Вот код, который делает получение:

private async Task StartReceiveLoop() 
{ 
await Task.Yield(); 

while(!_readOpCancelToken.IsCancellationRequested) 
{ 
    try 
    { 
     var buffer = new byte[4096]; 
     int bytesRx = await _pipe.ReadAsync(
      buffer, 0, buffer.Length, _readOpCancelToken); 

     Logger.LogInfo("Pipe connection: Got " + bytesRx + " bytes"); 

     if (bytesRx == 0) break; 
     if (_readOpCancelToken.IsCancellationRequested) break; 

     await _receivedDataStream.WriteAsync(buffer, 0, bytesRx); 

     if (_pipe.IsMessageComplete) 
     { 
      // Get out the routing data 
      _receivedDataStream.Position = 0; 
      byte[] intbuffer = new byte[4]; 

      _receivedDataStream.Read(intbuffer, 0, 4); 
      int size = BitConverter.ToInt32(intbuffer, 0); 

      _receivedDataStream.Read(intbuffer, 0, 4); 
      int typeId = BitConverter.ToInt32(intbuffer, 0); 

      _receivedDataStream.Read(intbuffer, 0, 4); 
      int routeTag = BitConverter.ToInt32(intbuffer, 0); 

      messageObj = messageObj = Serializer.NonGeneric.Deserialize(messageType, _receivedDataStream); 

      // Process message on UI thread via tick queue 
      TickSystem.OneTimeTickQueue.Enqueue(new Action(() => 
      { 
       ProcessMessageExtApp.ProcessThisMessage(messageObj); 
      })); 

      // Reset the stream 
      _receivedDataStream = new MemoryStream(); 
     } 
    } 
    catch (Exception e) 
    { 
     Logger.LogError(
      "Exception in StartReceiveLoop():" + 
      "Message: " + e.Message + 
      "Stack Trace: " + e.StackTrace); 

     if (e.InnerException != null) 
     { 
      Logger.LogError(
      "Inner Exception in StartReceiveLoop():" + 
      "Message: " + e.InnerException.Message + 
      "Stack Trace: " + e.InnerException.StackTrace); 
     } 
    } 
} 

}

+0

Ваша логика приема нарушена, это не ошибка протофуфа. Вы передаете неполные данные. Не уверен, что вы подразумеваете под побегом. Отправьте код, который отвечает за передачу данных в protobuf. Вероятно, вы также должны исправить ваш журнал, поскольку данные об ошибках, похоже, отсутствуют. Лучше всего регистрировать полное исключение ToString. – usr

+0

Выглядит хорошо. Как насчет исключений? Обработка нарушена, потому что вы будете продолжать цикл навсегда в случае ошибки. Также отправьте код отправки, потому что я не могу обнаружить проблему с кодом чтения. – usr

ответ

1

Реальная проблема не была Protobuf-сеть, но факт, что IsMessageComplete был сигнал преждевременно. Фиксирование заключалось в том, чтобы писать в трубку на сервере трубопроводов, используя байт-массив, вместо этого копировать поток и очищать трубу после завершения каждого пакета.

Смежные вопросы