我正在尝试在TCP套接字上实现Boost.Asio读取的超时。
我正在尝试将async_read_some
与deadline_timer
一起使用。我下面的函数是一个类的成员,该类包含一个指向TCP套接字和io_service
的智能指针。当在没有返回任何数据的活动套接字上调用时,期望会发生等待2秒并返回false 。
会发生什么:如果套接字永远不会返回任何数据,它会按预期工作。然而,如果服务器返回数据,则继续调用下面的方法立即返回,因为调用定时器回调而不等待两秒钟。
我尝试评论async_read_some
调用,该函数始终按预期工作。为什么async_read_some
会改变计时器的工作方式?
client::client() {
// Init socket and timer
pSock = boost::shared_ptr<tcp::socket > (new tcp::socket(io_service));
}
bool client::getData() {
// Reset io_service
io_service.reset();
// Init read timer
boost::asio::deadline_timer timer(pSock->io_service());
timer.expires_from_now(boost::posix_time::seconds(2));
timer.async_wait(boost::bind(&client::read_timeout, this, boost::system::error_code(), true));
// // Async read the data
pSock->async_read_some(boost::asio::buffer(buffer_),
boost::bind(&client::read_complete,
this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
));
// While io_service runs check read result
while (pSock->io_service().run_one()) {
if (m_read_result > 0) {
// Read success
return m_read_result;
}else if(m_read_result < 0){
return false;
}
}
}
}
void client::read_complete(const boost::system::error_code& error, size_t bytes_transferred) {
if (!error) {
m_read_result = bytes_transferred;
}else{
m_read_result = -1;
}
}
void client::read_timeout(const boost::system::error_code& error, bool timeout) {
if(!error){
m_read_result = -1;
}
}
答案 0 :(得分:1)
设置定时器时的简单问题boost :: system :: error_code()应更改为_1或error :: placeholder
timer.async_wait(boost::bind(&client::read_timeout, this, _1, true));
答案 1 :(得分:0)
检查连接错误时,您已取消了条件。
应该是:
if(error){
std::cout << "read_timeout Error - " << error.message() << std::endl;
}
现在您将看到,使用错误代码boost::asio::error::operation_aborted
调用回调。
这是因为,当您收到任何数据时,您从函数getData
返回,而deadline_timer
的析构函数会调用带有错误代码集的回调。