boost :: asio :: async_read не вызывает мой обработчик

Я работаю с boost::asio за TCP общение между клиентом & Серверное приложение, оба из которых написаны мной. Я изначально написал это с синхронным чтением данных, которое использует boost::asio::read, sync_read работает все хорошо, за исключением того, что я не могу так сделать socket.cancel во время операции чтения. Это стало довольно сдерживающим фактором & следовательно Я сейчас пытаюсь преобразовать мое синхронное чтение, чтобы сделать async_read механизм.

Ниже был мой механизм синхронного чтения, который действительно хорошо. Я делаю 2 чтения. Сначала получите заголовок пакета, затем получите данные пакета, которые работают довольно хорошо ->

size_t Read_Data_Sync(std::vector<unsigned char> & msg_body) {
//fetch the header
MyMessageHeader msg_header;
boost::system::error_code err_code;
size_t bytes_received = boost::asio::read(socket, boost::asio::buffer(&msg_header, sizeof(msg_header)), err_code);

if (bytes_received <= 0 || err_code)
return 0;

err_code.clear();
msg_body.resize(msg_header.size);

//fetch the body
bytes_received = boost::asio::read(socket, boost::asio::buffer(msg_body), err_code);
if (bytes_received <= 0 || error_code)
return 0;

return bytes_received;
}

Выше функция используется для непрерывного вызова из thread на стороне клиента, который я называю потоком читателя like so ->

auto data_reader_thread = std::thread {[this] {
while(run_thread) {
Read_Data_Sync();
}
}};

Вот как я изменяю это, чтобы сделать механизм чтения async ->

Поток чтения остается таким же, за исключением того, что теперь он вызывает другую функцию чтения, которую я кодировал для чтения данных в async путь

auto data_reader_thread = std::thread {[this] {
while(run_thread) {
Read_Data_Async();
}
}};

Я сделал msg_body & msg_header как переменные-члены в моем классе. Обновленная логика такова, что Read_Data_Async вызывается из функции потока непрерывно. Read_Data_Async звонки boost::asio::async_read переплет
адрес Handle_Read_Header в качестве обратного вызова, который в свою очередь снова делает boost::asio::async_read читать тело сообщения, передавая обработчик обратного вызова для получения message_body

void Read_Data_Async()
{
//firstly read message header
MyMessageHeader msg_header;
boost::asio::async_read(socket, boost::asio::buffer(&msg_header, sizeof(msg_header)), boost::bind(&TCPSession::Handle_Read_Header, this,
boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}

void Handle_Read_Header(const boost::system::error_code & error, std::size_t bytes_transferred)
{
//now read the message body
if (!error && bytes_transferred > 0) {
boost::asio::async_read(socket, boost::asio::buffer(msg_body), boost::bind(&TCPSession::Handle_Read_Body, this,
boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}
else {
cout << "Error: " << error << "\n";
}
}void Handle_Read_Body(const boost::system::error_code & error, std::size_t bytes_transferred)
{
if (!error && bytes_transferred > 0) {
// msg_body has the data read from socket
}
else if (error != boost::asio::error::eof) {
cout << "Error: " << error << "\n";
}
}

Проблема, с которой я сталкиваюсь сейчас, заключается в том, что обратный вызов Handle_Read_Header никогда не перезвонят !! Что не так с тем, что я делаю? Я просмотрел довольно много похожих постов, таких как этот пытаясь решить мой
проблема, но опять же, что ссылка предлагает позвонить io.run потому что о boost::asio::async_read_until не boost::asio::async_read,

Правильна ли моя приведенная выше логика по отношению к boost::asio::async_read ? Что я должен получить asio перезвонить моей функции обработчика?

0

Решение

Ты должен бежать io_service::run() где-то ¹

На самом деле, вся идея асинхронного ввода-вывода заключается в том, что вы делаете НЕ нужны отдельные потоки для чтения / записи: полный дуплекс полностью возможен в одном потоке.


¹ или более сложный цикл с run_one, poll или poll_one

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector