#c #serialization #flatbuffers
#c #сериализация #плоские буферы
Вопрос:
Я использую плоские буферы для публикации потока объектов в режиме реального времени. Одна проблема, с которой я столкнулся, заключается в том, как разделять независимые объекты / буферы. Если я использую некоторые символы, такие как '1'
или '|'
, то нет гарантии, что эти символы не появятся в сериализованном буфере. Какой рекомендуемый способ сделать это?
while (more object) {
flatbuffers::Offset<Msg> m = foo::CreateMessage(...);
socket.send('|');
socket.send(fbb.GetBufferPointer(), fbb.GetSize());
socket.send('|');
}
Комментарии:
1. Разве вы не можете отправить размер буфера в начале (скажем, 4 байта в начале), а затем отправить содержимое? Обычно заголовки пакетов работают именно так, правильно? Тогда вам не понадобились бы разделители.
2. Тогда нет способа получить начало буфера, предположим, что мы находимся в середине буфера.
3. Является ли ваш контент «потоковым»? Знаете ли вы размер содержимого, которое собираетесь отправить, прежде чем начать передачу? Даже если в противном случае, вы можете использовать тот же метод. Получатель должен реализовать логику для чтения первых 4 байт (например) как длины следующего содержимого.
4. Что, если клиент запустился в середине буфера?
Ответ №1:
Используйте «буфер с префиксом длины» (см. FlatBufferBuilder::FinishSizePrefixed
и GetRootSizePrefixed
) как на отправляющей, так и на принимающей стороне.
Вы пытаетесь использовать методы разделения текстовой базы и синтаксического анализа с двоичным буфером. Это никогда не сработает. Вам нужно убедиться, что ваш протокол полностью в двоичном формате.
Комментарии:
1. Что, если клиент запустился в середине буфера? есть ли способ удалить незавершенный буфер?
2. Это не сработает, потому что нет гарантии, что полученный вами буфер из сети начинается с boinbdary.
3. Вы не можете начать чтение данных с середины.. это не будет работать с двоичными данными, такими как плоские буферы, или даже с текстовыми данными, такими как JSON. Вам нужно убедиться, что ваш транспортный метод может получать байты последовательно с самого начала. Практически любая система допускает это. Если вы получаете несколько частей по сетевому протоколу, вам нужно сначала объединить их, пока вы не прочитаете полный объект. Если подключается новый клиент, ему необходимо начать получать данные, начиная с начала объекта.
4. Проблема в том, что это приведет к ошибкам во всех сообщениях, даже если только одно сообщение повреждено или искажено, вот почему нам нужен способ отбросить плохое сообщение и начать все заново.
5. Другая проблема заключается в том, что даже если вы получаете с самого начала, вы можете получить половину сообщения, и в этом случае префикс size не поможет.