我正在使用 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_body
和 msg_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/