Я делаю синхронный чтение/запись с использованием boost-asio. Данные поступают в двоичном формате без границ, информация о длине кодируется в формате пакета. Поэтому важно читать с указанным размером. Может ip::tcp::iostream
сделать это? Может ли кто-нибудь привести пример? Благодарю.Как читать пакет размером с фиксированным размером, используя boost asio?
ответ
Я работаю над программой, которая отправляет разные данные разного размера. Я использую фиксированный заголовок 8 байт для кодирования размера, то я добавляю данные:
enum { header_length = 8 }; //const header length
я получить размер (m_outbound_data является станд :: строка == сериализованная объект)
//give header length
std::ostringstream header_stream
header_stream << std::setw(header_length) //set a field padding for header
<< std::hex //set next val to hexadecimal
<< m_data_out.m_outbound_data.size(); //write size in hexa
m_data_out.m_outbound_header = header_stream.str(); //m_outbound_head == size in hexa in a std::string
//m_outbound_header = [ 8 byte size ]
//m_outbound_data = [ serialized data ]
//write all data in the std::vector and send it
std::vector<boost::asio::const_buffer> buffer;
buffer.push_back(boost::asio::buffer(m_data_out.m_outbound_header));
buffer.push_back(boost::asio::buffer(m_data_out.m_outbound_data));
и для чтения, вы должны прочитать в 2 раза: первый прочитал 8 байт, чтобы получить размер, а затем прочитать данные в векторе и десериализации в объекте:
struct network_data_in {
char m_inbound_header[header_length]; //size of data to read
std::vector<char> m_inbound_data; // read data
};
Я использую эту структуру, чтобы получить данные, вызов читать на m_inbound_header для заполнения буфер с размером, а затем, в ручке:
//get size of data
std::istringstream is(std::string(m_data_in.m_inbound_header, header_length));
std::size_t m_inbound_datasize = 0;
is >> std::hex >> m_inbound_datasize;
m_data_in.m_inbound_data.resize(m_inbound_datasize); //resize the vector
затем называют еще раз перечитал с m_inbound_data на буфер, этот результат чтения именно данные отправленного Во втором handle_read вы Juste должны десериализации данные:
//extract data
std::string archive_data (&(m_data_in.m_inbound_data[0]),m_data_in.m_inbound_data.size());
std::istringstream archive_stream(archive_data);
boost::archive::text_iarchive archive(archive_stream);
archive >> t; //deserialize
Надеюсь, что вам помогут!
+1 хороший ответ, вот что я хотел бы предложить. Измените свой протокол, чтобы включить заголовок длины исправления. Если вы не можете изменить свой протокол, укажите это в вопросе. –
TCP - это протокол, основанный на потоке. Это означает, что все, что вы читаете, это просто поток байтов. Рассмотрим пример: у вас есть сообщение фиксированного размера, и вы отправляете его по TCP. Как программа на другом конце может прочитать все сообщение? существует два способа: один из них должен окружать ваше сообщение с помощью контрольных кураторов (например, STX при запуске и ETX в конце). Вначале программа будет отбрасывать любые символы перед STX, а затем читать любые другие символы в буфере сообщений до тех пор, пока не встретится ETX.
Другим способом является кодирование длины сообщения в заголовке фиксированного размера (что, по-видимому, является вашим случаем). Поэтому самое лучшее, что вы можете сделать, это выяснить способ чтения длины сообщения, проанализировать его и соответственно прочитать оставшиеся байты.
Я понимаю, что вам нужна информация о длине, то есть данная. Непонятно указывать эту длину (количество байтов, которые я хочу читать) в API. – Oliver
@ Оставь свой комментарий не имеет смысла. Количество прочитанных байтов хорошо документировано в таких API, как ['boost :: asio :: read'] (http://www.boost.org/doc/libs/1_48_0/doc/html/boost_asio/reference/read/ overload1.html) –
Простой:
boost::asio::read(socket, buffers, boost::asio::transfer_exactly(your_fixed_size));
- 1. Контейнер с фиксированным размером
- 2. Подменю с фиксированным размером
- 3. Установить раздел с фиксированным размером
- 4. Получить Картинку с фиксированным размером
- 5. Изображение контейнер с фиксированным размером
- 6. Параллельной Карте с фиксированным размером
- 7. Dynamic GridLayout с фиксированным размером
- 8. Конкретный список с фиксированным размером
- 9. массив с фиксированным интервалом размером
- 10. android scrollableTabs с фиксированным размером
- 11. Реализация jpeg-изображения с размером javascript с фиксированным размером
- 12. ode solver с фиксированным размером шага
- 13. Как сфотографироваться в файл с фиксированным размером?
- 14. Как создать подкласс UIView с фиксированным размером?
- 15. Как читать пакет в повышение :: ASIO
- 16. создать эскиз с фиксированным размером codeignitor;
- 17. масштабируемый SVG с фиксированным размером границы
- 18. Создать тип - массив полукокса с фиксированным размером
- 19. Аргументы многомерного массива с фиксированным размером
- 20. Многомерные массивы Javascript с фиксированным размером
- 21. Создать файл с фиксированным размером в Cocoa
- 22. Компоненты в сетке с фиксированным размером
- 23. Нижний край границы с фиксированным размером
- 24. WebView с фиксированным размером нижней части приложения
- 25. Только для контейнеров с фиксированным размером только
- 26. Минимизировать рамку с фиксированным размером в wxPython
- 27. Sum-подмножество с фиксированным размером подмножества
- 28. JAVA - сохранить изображение с фиксированным размером
- 29. Установите img в контейнер с фиксированным размером
- 30. Структура с фиксированным размером массива другого объекта
Что вы имеете в виду: * информация о длине кодируется в формате пакета *? Кадрирование протоколов обычно выполняется на уровне приложений, я думаю, вы запутываете себя, думая о пакетах вместо потока данных. –