Я использую TCP-сервер, который использует asio socket.async_read() и boost :: asio :: async_read_until() методы для асинхронных данных чтения из сокета. Оба используют один и тот же обработчик для чтения данных из boost :: asio :: streambuf.boost :: asio :: streambuf - как повторно использовать буфер?
Обработчик, который прекрасно работает вызывается через async_read():
void handle_read(const boost::system::error_code& ec, std::size_t ytes_transferred))
{
m_request_buffer.commit(bytes_transferred);
boost::asio::streambuf::const_buffers_type rq_buf_data = m_request_buffer.data();
std::vector<uint8_t> dataBytes(boost::asio::buffers_begin(rq_buf_data), boost::asio::buffers_begin(rq_buf_data) + bytes_transferred);
//process data here
m_request_buffer.consume(bytes_transferred);
bytes_transferred = 0;
}
Мой сервер в зависимости от обработки данных может подключение выключения или продолжить чтение через тот же сокет.
Но, если handle_read() вызывается из вызова 2-го boost :: asi :: async_read_until(), я получаю количество нулей в dataBytes, а затем верны действительные данные.
Я попробовал простой тестовый чехол и узнал, что после записи данных в streambuf и commit() + потребляет() данные в streambuf по-прежнему сохраняют предыдущий буфер.
Итак, есть ли способ очистить данные в boost :: asio :: streambuf и повторно использовать его в boost :: asio :: async_read_until()?
Если скомпилирован с USE_STREAM = 1, живой пример работает отлично. Но что std :: istream делает по-разному по сравнению с buffer consumume()?
Спасибо за замечание. Наконец, я посмотрел на boost :: asio :: async_read_until() и выяснил, что это streambuf_.commit (bytes_transferred) ;. Поэтому я не должен называть commit() в моем обработчике.Но в случае использования boost :: asio :: ip :: tcp :: socket.async_read() мой обработчик должен вызвать commit() для перемещения символов из выходной последовательности в последовательность ввода. – drus
@drus нет, вы не должны. Не вмешивайтесь в какие-либо из этих операций. Все, что я когда-либо делал, это вызов 'buffer.consume (buffer.size() + 1)', потому что гарантированно полностью очистить буфер. –
Да, я переключился на использование boost :: asio :: async_read() и boost :: asio :: async_read_until(), и он работает как ожидалось. Как я уже сказал, оба эти метода называют streambuf.commit(). – drus