Кажется, ваша проблема - запуск асинхронных операций, которые переводят буфер в локальные переменные.
auto listener::write(packet barray, std::function<void(std::error_code ec, std::size_t length)> callback) noexcept
-> void {
asio::async_write(*m_socket, asio::buffer(barray), callback);
}
barray
- локальная переменная внутри write
, async_write
возвращается немедленно, но asio::buffer()
возвращает толькоОбертка для передаваемых данных (указатель на данные и их размер), данные не копируются.write
заканчивается, barray
уничтожается и async_write
получает буфер для удаленных данных ..
То же самое с
auto listener::read(std::function<void(std::error_code ec, packet barray)> callback) noexcept -> void {
packet tmp;
tmp.resize(1);
asio::async_read(*m_socket, asio::buffer(tmp), asio::transfer_exactly(1),
[&](std::error_code ec, std::size_t size) {
if (!ec) {
const auto available = m_socket->available();
m_buffer.resize(available);
m_buffer.shrink_to_fit();
asio::async_read(*m_socket, asio::buffer(m_buffer), asio::transfer_all());
}
callback(ec, std::move(m_buffer));
});
async_read
занимает buffer(tmp)
, где tmp
местныйasync_read
также немедленно возвращается, поэтому, когда вызывается обработчик, tmp
не существует.
EDIT
Несколько слов о listener::read
методе:
auto listener::read(
std::function<void(std::error_code ec, packet barray)> callback) noexcept -> void // [1]
{
packet tmp;
tmp.resize(1);
asio::async_read(*m_socket, asio::buffer(tmp), asio::transfer_exactly(1),
[&](std::error_code ec, std::size_t size) { // [2]
if (!ec) {
const auto available = m_socket->available();
m_buffer.resize(available);
m_buffer.shrink_to_fit();
asio::async_read(*m_socket, asio::buffer(m_buffer), asio::transfer_all()); // [3]
}
callback(ec, std::move(m_buffer)); // [4]
});
}
[1] обратный вызов передается по значению
[2] лямбда-захватывает все по ссылке , поэтому копия callback
не создается, закрытие сохраняет ссылку налокальная переменная, в [4] вы вызываете замыкание callback(ec,std::move(m_buffer))
, которое висит, потому что async_read
возвращается немедленно, а listener::read
заканчивается
[3] с [4] странно, async_read
возвращается немедленно, вы передали buffer
в m_buffer
при вызове ayns_read
, async_read
возвращает (выполняется асинхронное чтение) и вызывается обратный вызов, который перемещает m_buffer
(он меняет объект, который используется асинхронной операцией!),вам следует подождать, пока не будет вызван обработчик для async_read
, затем вы можете переместить m_buffer
в обратный вызов
Основная проблема : На мой взгляд, проблема с передачей callback
по ссылке в listener::read
метод.Когда вызывается обработчик, он вызывает callback(..)
по висячей ссылке.Попробуйте передать callback
по значению:
[&,callback /*pass by value*/](std::error_code ec, std::size_t size)
{
if (!ec)
{
const auto available = m_socket->available();
m_buffer.resize(available);
m_buffer.shrink_to_fit();
asio::async_read(*m_socket, asio::buffer(m_buffer), asio::transfer_all());
}
callback(ec, std::move(m_buffer));
});