boost :: async_write вызывает повреждение данных

В настоящее время я использую boost :: async_write для отправки буфера большого размера (около 50 КБ) один раз. В результате я получаю примерно один поврежденный буфер на каждые 20 буферов на стороне сервера.

Мой код такой. Обработка ошибок и другие подробности опускаются:

bool socket_available = true;
const_buffer *buffer;

// will be called frequently in a while loop in thread A
void send_buffer()
{
    scope_lock l(mutex);
    if (!socket_available) return;

    socket_available = false;
    buffer = get_buffer_for_send();   // The size is about 50KB
    boost::asio::async_write(
        socket, buffer,
        boost::bind(handle_write_request, boost::asio::placeholders::error)
    );
}

// will be called in thread B which runs io_service::run
void handle_write_request(const boost::system::error_code& error_code)
{
    scope_lock l(mutex);
    socket_available = true;
    free_buffer(buffer);
}

Я считаю, что правильно использую async_write, потому что я вызываю async_write только один раз после вызова обработчика (http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/async_write/overload1.html). Однако при отправке данные все еще кажутся чередующимися.

Я знаю, что обычный способ сделать это - поместить async_write в обработчик, чтобы они оба вызывались в одном потоке. И когда я это делаю, повреждение данных больше не происходит. Поэтому мне просто интересно, почему приведенный выше код не работает должным образом.

Спасибо за ваше время и советы. Кстати, я использую boost 1.54.0 под win 7.


person user2028206    schedule 22.08.2013    source источник
comment
Синхронизация сокетов выглядит нормально и правильно работает в программе-макете, которую я написал. Остается еще немало неизвестных (протокол сокета, использование сокета в других потоках, фактический буфер); однако, если вы предоставите sscce, возможно, мы сможем лучше вам помочь.   -  person Tanner Sansbury    schedule 22.08.2013


Ответы (1)


Поскольку ваша отправка асинхронна, буфер должен оставаться нетронутым в течение всего времени. Я не могу сказать этого из вашего кода, например, использование глобальной переменной неверно. Что произойдет с двумя посылками одновременно? Кроме того, get_buffer_for_send() не отображается, он тоже может содержать проблемы.

person Codeguard    schedule 22.08.2013