Буферы протокола, что в сериализованных данных?
Я новичок в буферах протоколов и очень хочу узнать об этом больше, так что извините за вопрос noob.
Что находится в сериализованных данных, только значения или и ключи и значения? Я думаю, что есть только ценности, и если кто-то хочет десериализовать его, он / она должен иметь схему.
2 ответа
Это и ключ, и ценность:
Как вы знаете, буферное сообщение протокола представляет собой серию пар ключ-значение. Бинарная версия сообщения просто использует номер поля в качестве ключа - имя и объявленный тип для каждого поля могут быть определены только в конце декодирования путем ссылки на определение типа сообщения (то есть файл.proto). https://developers.google.com/protocol-buffers/docs/encoding
Например, скажем, у вас есть файл прото как:
$ cat my.proto
message header {
required uint32 u1 = 1;
required uint32 u2 = 2;
optional uint32 u3 = 3 [default=0];
optional bool b1 = 4 [default=true];
optional string s1 = 5;
optional uint32 u4 = 6;
optional uint32 u5 = 7;
optional string s2 = 9;
optional string s3 = 10;
optional uint32 u6 = 8;
}
Извлечь закодированные данные из памяти:
(gdb) x/10xb 0x7fd70db7e964
0x7fd70db7e964: 0x08 0xff 0xff 0x01 0x10 0x08 0x40 0xf7
0x7fd70db7e96c: 0xd4 0x38
Decode:
$ echo 08ffff01100840f7d438 | xxd -r -p | protoc --decode_raw
1: 32767
2: 8
8: 928375
1,2,8 являются ключами
из файла прото выше:
1 => u1,
2 => u2,
8 => u6
Итак, это становится:
u1: 32767
u2: 8
u6: 928375
Я использовал данные из моего вопроса здесь:
Это немного зависит от того, используете ли вы двоичную форму (которая обычно используется по умолчанию при работе с protobuf) или форму json (да, protobuf включает опцию json, по крайней мере, в некоторых библиотеках - не во всех).
В двоичной форме данные состоят из номеров полей и значений; не имена полей. В качестве примера, если мы используем пример:
optional string name = 1; // remove the "optional" if using proto3 syntax
и назначить значение "Ника" (и сериализовать его), тогда двоичные данные будут включать 1
(в слегка подправленной форме) и в кодировке UTF-8 Nika
, но он не будет содержать "имя".
Вам не обязательно иметь схему для ее декодирования, но если вы сделаете это, вам будет намного проще, так как многие части спецификации являются неоднозначными, используя один и тот же "тип провода" (т. Е. Формат кодирования) для несколько типов данных или для нескольких значений одного и того же типа данных (например: вы не можете сказать, является ли целое число со знаком, без знака или "закодировано зигзагом" без схемы (или правильного предположения) и фактического значения что вы можете получить может сильно варьироваться в зависимости от этого.
Чтобы увидеть, что вы можете получить из необработанных данных protobuf без схемы, попробуйте: https://protogen.marcgravell.com/decode