【发布时间】:2017-01-08 13:40:10
【问题描述】:
我正在与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 永远不会被回调! 我在做什么有什么问题?我浏览了很多相关的帖子,比如this one 试图解决我的问题
问题,但该链接再次建议调用io.run,因为它是关于boost::asio::async_read_until 而不是boost::asio::async_read。
我的上述逻辑对boost::asio::async_read 是否正确?我应该得到什么asio 来回调我的处理函数?
【问题讨论】:
-
哪个线程调用
io_service对象上的run()? -
我的主线程调用
io_service::run()&io_service在主线程上。如何使用单独的阅读器线程进行这项工作?
标签: c++ boost boost-asio asyncsocket