Я собираюсь прочитать сообщения, которые последовательно хранятся в сокете клиента C ++ и отправляются с сервера C #. Я ожидаю, что смогу прочитать размер такого сообщения:
google::protobuf::uint32 m;
coded_input->ReadVarint32(&m);
cout << m << endl;
Затем я хочу прочитать сообщение:
Person person;
CodedInputStream::Limit limit = coded_input->PushLimit(m);
person.ParseFromCodedStream(coded_input);
coded_input->PopLimit(limit);
код C # выглядит так:
var person = new Person { Id = 123456, Name = "Fred", Address = new Address { Line1 = "Flat 1", Line2 = "The Meadows ar garą " } };
Stream str = new NetworkStream(socket);
Serializer.SerializeWithLengthPrefix(str, person, PrefixStyle.Fixed32);
Не работает.
Я получаю сообщение об ошибке C ++ (43 - результат cout ‹< m ‹< endl;) (id, name, address - все поля в Person)
43
libprotobuf ОШИБКА google / protobuf / message_lite.cc: 123] Невозможно проанализировать сообщение типа "Человек", так как в нем отсутствуют обязательные поля: идентификатор, имя, адрес
Когда я не читаю вариант и не разбираю сообщение прямо из coded_input
, все в порядке (когда я изменяю SerializeWithLengthPrefix
на сериализацию в коде сервера). Однако мне нужен способ различать последовательные сообщения, поэтому мне нужно знать размер сообщения, которое я собираюсь прочитать. Я просто не знаю, как отправить размер.
Я пытался:
Stream buf = new MemoryStream();
Serializer.Serialize(buf, person);
ProtoWriter writer = new ProtoWriter(str, null);
ProtoWriter.WriteInt32((int)buf.Length, writer);
но потом я получаю:
Необработанное исключение: ProtoBuf.ProtoException: недопустимая операция сериализации с проводным типом Нет в позиции 0 в ProtoBuf.ProtoWriter.WriteInt32 (значение Int32, модуль записи ProtoBuf.ProtoWriter) [0x00000] в: 0
в protobuftest.MainClass.Main (System .String [] args) [0x00097] в /home/lorddidger/studia/csharp/protobuf-test/protobuf-test/Main.cs:31
Я не могу отправить таким образом int. Что случилось?
Обновление: на самом деле моя цель - найти способ передать целое число (размер) с помощью protobuf. Мне нужен какой-либо пример (как C ++, так и C #), как с этим справиться, потому что я не понимаю всех деталей в protobuf.
Я заметил, что SerializeWithLengthPrefix отправляет префикс (4 uint32), который выглядит так: size 0 0 0. Размер - это количество байтов сообщения после сериализации (я думаю). Я думал, что PrefixStyle.Fixed32 говорит, что перед сообщением только один uint32, но их четыре!
Наконец, я подумал, что вам следует использовать ProtoWriter.WriteInt32 ((int) buf.Length, writer) для передачи целых чисел, потому что я следовал совету где-то в Интернете, что, как я полагаю, является обходным путем, относящимся к C ++. Теперь я вижу, что вам не следует писать варинты - они связаны с движком и слишком сложны, чтобы тратить на них время.
Должен ли я отправлять сообщение с int? Как отличить это сообщение от следующего, размер которого хранится в первом?
Я вижу, что C # может нормально обрабатывать префиксы, но есть ли ЛЮБОЙ СОВМЕСТИМЫЙ с C ++ и C # способ указать размер сообщения? В противном случае не существует * * способа поставить сообщения в очередь, что я считаю иррациональным.