#c #serialization #flatbuffers
#c #сериализация #плоские буферы
Вопрос:
Я получаю объекты плоских буферов из сети, я использую буферы с префиксом размера, как указано в документации. Я провожу проверку перед фактическим удалением данных. Проблема в том, как мне узнать, какой размер буфера я должен проверить?
buff = recv(sock);
Verifier v(buff.data(), ???); // buffer could be half of a buffer or two buffers, what should I supply to the 2nd argument to Verifier?
bool f = VerifySizePrefixedMessageBuffer(v);
Поскольку буфер, полученный из сети, может быть любого размера, это может быть половина плоского буфера или два буфера, но мне нужно будет указать Verifier размер одного буфера сообщений. Есть ли способ сделать это?
Ответ №1:
Вы должны каким-то образом уведомить получателя о том, что отправка буфера завершена, и вы должны сделать это вручную.
Если вы используете буферный подход с префиксом размера, то размер буфера должен быть отправлен получателю данных в первых байтах буфера. Когда принимается первая часть буфера, получатель должен считывать размер данных из первых байтов полученного буфера и делать recv()
это до тех пор, пока все данные не будут переданы (пока сумма размеров всех полученных частей буфера не будет равна общему размеру отправленного буфера, который вы уже знаете из самой первой полученной части буфера).
На стороне получателя это должно выглядеть так:
buff = recv(sock);
uint32_t received = buff.size();
auto totalBuff = buff;
// I assume you have 4 bytes for unsigned integer buffer size prefix
while (received < 4) { // receive whole buffer size prefix data
buff = recv(sock);
received = buff.size();
// append new data to total data buffer
totalBuff.insert(totalBuff.end(), buff.begin(), buff.end());
}
uint32_t totalSize = *(reinterpret_cast<uint32_t>(totalBuff.data());
while (received < totalSize) {
buff = recv(sock);
received = buff.size();
// append new data to total data buffer
totalBuff.insert(totalBuff.end(), buff.begin(), buff.end());
}
// do whole buffer data processing
ProcessSizePrefixedBuffer(totalBuff);
В этом totalBuff
случае размер данных будет в первых 4 байтах буфера. Это скорее псевдокод, чем рабочий код, поскольку я не знаю вашего фактического buff
типа и других деталей реализации.
Комментарии:
1. Я стараюсь избегать приведения буфера непосредственно к uint32_t. Мне это кажется неправильным. Я не понимаю, почему сгенерированное сообщение не имеет
GetSize
метода.2. @fluter Вам все равно придется интерпретировать эти данные вручную, если вы используете какой-то низкоуровневый API сокетов. Или ваш фреймворк сокетов может выполнить за вас некоторую работу, но я не могу точно сказать, потому что я не знаю, какую реализацию сокетов вы используете. Покажите
recv()
иbuff
введите реализацию.