Существуют ли особые требования при использовании 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);
}
}
}
}
Ваша логика приема нарушена, это не ошибка протофуфа. Вы передаете неполные данные. Не уверен, что вы подразумеваете под побегом. Отправьте код, который отвечает за передачу данных в protobuf. Вероятно, вы также должны исправить ваш журнал, поскольку данные об ошибках, похоже, отсутствуют. Лучше всего регистрировать полное исключение ToString. – usr
Выглядит хорошо. Как насчет исключений? Обработка нарушена, потому что вы будете продолжать цикл навсегда в случае ошибки. Также отправьте код отправки, потому что я не могу обнаружить проблему с кодом чтения. – usr