c++ - boost::asio::async_read 不回调我的处理函数

标签 c++ boost boost-asio asyncsocket

我正在使用 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;
}

以上函数用于从客户端的线程连续调用,我将其称为读取器线程like so ->

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

以下是我如何更改它以使读取机制 async ->

读取器线程保持不变,除了它现在调用另一个读取函数,我已经编码该函数以异步方式读取数据

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

我已将 msg_bodymsg_header 作为我类中的成员变量。更新的逻辑是 Read_Data_Async 被线程函数连续调用。 Read_Data_Async 调用 boost::asio::async_read 绑定(bind) 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 永远不会被回调!!我在做什么有什么问题吗?我浏览了很多相关的帖子,比如 this one试图解决我的 问题,但该链接再次建议调用 io.run 因为它是关于 boost::asio::async_read_until 而不是 boost::asio::async_read

对于 boost::asio::async_read 我的上述逻辑是否正确?我应该得到什么 asio 来回调我的处理函数?

最佳答案

你必须在某处运行 io_service::run() ¹

实际上,执行异步 IO 的整个想法是您不需要需要单独的线程来读取/写入:在单个线程上完全双工是完全可能的。


¹ 或使用 run_one、poll 或 poll_one 的更复杂的循环

关于c++ - boost::asio::async_read 不回调我的处理函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41533313/

相关文章:

c++ - boost::asio::deadline_timer 是否为每个计时器使用一个线程?

c++ - boost asio SSL 服务器错误 : called a function you should not call

c++ - 使用 boost io_service 初始化 boost udp 套接字时出错

C++ Qt QtConcurrent::filteredReduced 从 std::shared_ptr 的 QVector

c++ - 从 boost::array 更改为 std::array 时出现错误

c++ - 当我知道我插入的指针时,如何从 boost::ptr_set 中删除?

python - 安装 ROS 时 Cmake 未检测到 boost-python

c++ - 将 char 更改为变量(初学者)

c++ - 取消引用成员指针错误 : cannot be used as member pointer

c++ - 如果 basic_waitable_timer 在仍有异步操作等待时被破坏怎么办?