Неиспользуемые байты при реализации protobuf (для реализации ограничителя)

Мне нужно передавать данные через последовательный порт. Чтобы обеспечить целостность данных, я хочу иметь небольшой протокол конверта вокруг каждого сообщения protobuf. Я думал о следующем:

  1. тип сообщения (1 байт)
  2. размер сообщения (2 байта)
  3. сообщение protobuf (N байт)
  4. (контрольная сумма; необязательно)

Тип сообщения в основном будет отображаться между сообщениями, определенными в файлах прото. Однако, если сообщение будет повреждено или некоторые байты будут потеряны, размер сообщения будет неправильным, и все последующие байты больше не будут интерпретироваться. Одним из способов решения этой проблемы было бы введение ограничителей между сообщениями, но для этого мне нужно выбрать что-то, что не используется protobuf. Есть ли последовательность байтов, которая никогда не используется ни одним сообщением protobuf?

Я тоже думал о другом способе. Если мастер обнаружит, что пакеты повреждены, он должен сбросить связь до чистого начала. Для этого я хочу, чтобы мастер отправил команду RESTART подчиненному. Подчиненный должен ответить ACK, а затем снова начать отправку полных сообщений. Все байты, полученные между RESTART и ACK, должны быть удалены мастером. Я хочу закодировать ACK и RESTART как специальные сообщения. Но при таком подходе я сталкиваюсь с той же проблемой: мне нужно найти последовательности байтов для ACK и RESTART, которые не используются никакими сообщениями protobuf.

Возможно, я тоже придерживаюсь неправильного подхода - не стесняйтесь предлагать другие подходы для обработки потерянных байтов.

2 ответа

Есть ли последовательность байтов, которая никогда не используется ни одним сообщением protobuf?

Нет; это двоичный сериализатор и может содержать произвольные двоичные полезные данные (особенно в bytes тип). Вы не можете использовать дозорные значения. Префикс длины в порядке (ваш заголовок "размер сообщения"), и контрольная сумма может быть прагматичным вариантом. В качестве альтернативы, вы можете наложить искусственного дозорного, чтобы он следовал за каждым сообщением (может быть, гид выбирал для каждого соединения как часть первоначального рукопожатия), и использовать это, чтобы перепроверить, что все выглядит правильно.

Один из способов восстановить синхронизацию пакетов после редкой проблемы - использовать слова синхронизации в начале сообщения и использовать контрольную сумму для проверки правильности сообщений.

Это означает, что вы ставите постоянное значение, например, 0x12345678, перед полем типа вашего сообщения. Затем, если сообщение не проходит проверку контрольной суммы, вы можете восстановить, найдя следующий 0x12345678 в ваших данных.

Даже если это значение иногда встречается в середине сообщения, это не имеет большого значения. Проверка контрольной суммы очень вероятно обнаружит, что в этой позиции нет реального сообщения, и вы можете искать вперед, пока не найдете следующий маркер.

Другие вопросы по тегам