Я собираюсь прочитать сообщения, которые последовательно хранятся в сокете в клиенте 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) </p>
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 [])[0x00097] в /home/lorddidger/studia/csharp/protobuf-test/protobuf-test/Main.cs:31
Я не могу отправить ни один int таким способом.Что не так?
Обновление: На самом деле моя цель - найти способ передать целое число (размер) с помощью protobuf.Мне нужен любой пример (как C ++, так и C #), как это сделать, потому что я не понимаю всех деталей в protobuf. * 1037 *
Я заметил, что SerializeWithLengthPrefix отправляет префикс (4 uint32), который выглядит следующим образом: размер 0 0 0.Размер - это количество байтов сообщения после сериализации (наверное).Я думал, что PrefixStyle.Fixed32 говорит, что перед сообщением есть только один uint32, но есть 4!
Наконец, я подумал, что вы должны использовать ProtoWriter.WriteInt32 ((int) buf.Length, writer) для передачи целых чисел, потому что япоследовало предложение от где-то в Интернете , которое, я полагаю, является обходным путем, относящимся к C ++.Теперь я вижу, что вы не должны писать varints - они связаны с движком, а это слишком сложно, чтобы тратить время на него.
Должен ли я отправить сообщение с int?Как мне отличить это от следующего сообщения, размер которого хранится в первом?
Я вижу, что префиксы хэдов C # могут работать нормально, но есть ли СООТВЕТСТВУЮЩИЙ С C ++ и C # способ указать размер сообщения?В противном случае ** не существует способа ставить в очередь сообщения, что я считаю иррациональным.