Каковы разделители для сообщений protobuf? Я работаю с сериализованными сообщениями. Я хотел бы знать, начинаются ли сообщения с $$ __ $$ и заканчиваются ли они тем же знаком.





Для сообщений верхнего уровня (т.е. отдельных вызовов сериализации) буквально нет ни одного. Если вы не добавите собственное кадрирование, сообщения активно перетекают друг в друга, поскольку десериализатор (по умолчанию) просто читает до конца потока. Итак: если вы слепо объединили несколько объектов без собственного протокола кадрирования: теперь у вас есть проблемы.
Для внутренней части сообщений есть два способа кодирования подобъектов - префикс длины и группы. Группы в значительной степени устарели, а кодирование подобъектов неоднозначно, поскольку это также те же маркеры, которые описывают строки, капли (байты) и «упакованные массивы». Вы, вероятно, не хотите пытаться справиться с этим.
Итак: похоже, вам нужно добавить свой собственный протокол кадрирования, и в этом случае ответ будет: все, что определяет ваш протокол кадрирования. Просто помните, что protobuf является двоичным, поэтому вы не можете полагаться на какую-либо последовательность байтов в качестве дозорного / терминатора. В идеале вы должны использовать вместо этого подход с префиксом длины.
Так ли обстоит дело с компилятором protobuf 2 и 3? Вы случайно не знаете? Я понимаю то, что вы пытаетесь объяснить. Это определенно то, что я должен пересмотреть в более широкой картине.
@MarkoBencik двоичный протокол идентичен независимо от того, какой DSL (proto2 / proto3), компилятор или другие инструменты вы используете. Сам бинарный протокол: не завершает внешние сообщения.
Формат проводного буфера протокола не является саморазграничивающим, поэтому анализаторы буфера протокола не могут самостоятельно определить, где заканчивается сообщение. Самый простой способ решить эту проблему - записать размер каждого сообщения до того, как вы напишете само сообщение. Когда вы читаете сообщения обратно, вы считываете размер, затем считываете байты в отдельный буфер, а затем выполняете синтаксический анализ из этого буфера.
(В дополнение к существующим ответам 1, 2)
Обычный метод кадрирования для буферов протокола заключается в добавлении варинт перед фактическим сообщением protobuf.
Реализация уже является частью библиотеки protobuf, например:
для java: MessageLite.writeDelimitedTo (), Parser.parseDelimitedFrom ()
для C: методы в заголовке google / protobuf / util / delimited_message_util.h (например, SerializeDelimitedToFileDescriptor())
Удачи тебе с твоим проектом!
РЕДАКТИРОВАТЬ> Официальная ссылка утверждает, что:
If you want to write multiple messages to a single file or stream, it is up to you to keep track of where one message ends and the next begins. The Protocol Buffer wire format is not self-delimiting, so protocol buffer parsers cannot determine where a message ends on their own. The easiest way to solve this problem is to write the size of each message before you write the message itself. When you read the messages back in, you read the size, then read the bytes into a separate buffer, then parse from that buffer. (If you want to avoid copying bytes to a separate buffer, check out the CodedInputStream class (in both C++ and Java) which can be told to limit reads to a certain number of bytes.)
Этот подход отлично работает, когда получатель получает байтовый поток с самого начала. Я не слишком хорошо знаком с байтовым потоком protobuf, но я не уверен, что он работает, если получатель получает поток байтов частично, так как может быть трудно различить разделительный varint и сообщение varint и т. д.
@bazza Я понимаю вашу точку зрения, но боюсь, что в вопросе нет такого требования. Кодирование Protobuf определенно не самосинхронизируется. Если возникает необходимость, существуют протоколы кадрирования, обладающие этим свойством (например, COBS). Я уверен, что в большинстве случаев целостность потока гарантируется верхним уровнем. Не стесняйтесь публиковать мысли с лучшим ответом ....
Нет, у меня нет лучшего ответа, ваш ответ отличный и, безусловно, отвечает на вопрос! Я просто хочу, чтобы Protobuf ввел самосинхронизацию, тогда это было бы еще более полезно. Спасибо за подсказку по COBS, я раньше крутил свой собственный (обычно мне это сходило с рук), но вместо этого приятно иметь библиотеку для этого.
После некоторого обсуждения и размышлений было принято решение добавлять заголовки к сообщениям для решения проблемы. Спасибо всем за вклад.