【发布时间】:2011-08-07 10:39:52
【问题描述】:
我们已经编写了一个基于 boost asio 的单线程客户端。客户端需要实现超时,这样如果在规定的时间段内没有完成对服务器的读取或写入,连接就会中断。但是在我不为 io_service 调用 run 之前,deadline_timer 的 async_wait 不会启动。现在,如果我在 io_service 上调用 run,那么我对服务器的读写是不可能的。
请查看我当前代码的摘录:
typedef boost::scoped_ptr<boost::asio::ip::tcp::socket> SocketPtr;
typedef boost::shared_ptr<boost::asio::deadline_timer> DLTPtr;
SocketPtr m_SocketPtrClient;
DLPtr m_ClientTimeoutDLTPtr;
boost::asio::io_service ios;
m_SocketPtrClient.reset( new boost::asio::ip::tcp::socket( ios));
m_ClientTimeoutDLTPtr.reset( new deadline_timer( ios));
m_ClientTimeoutDLTPtr->expires_from_now( boost::posix_time::seconds( m_uiCommTimeout));
m_ClientTimeoutDLTPtr->async_wait( boost::bind( &MyClass::clientTimeoutHandler,
this,
boost::asio::placeholders::error
)
);
m_SocketPtrClient->connect
(
boost::asio::ip::tcp::endpoint
(
boost::asio::ip::address::from_string
(
m_sCommAddress == "localhost" ? "127.0.0.1" : m_sCommAddress
), m_usCommPort
), ec
);
if( !ec && m_SocketPtrClient->is_open())
{
m_ClientTimeoutDLTPtr->cancel();
}
else
{
m_ClientTimeoutDLTPtr->cancel();
m_SocketPtrClient->close();
return eStateError;
}
//install a timeout handler
m_ClientTimeoutDLTPtr->expires_from_now( boost::posix_time::seconds( m_uiCommTimeout));
m_ClientTimeoutDLTPtr->async_wait( boost::bind( &MyClass::clientTimeoutHandler,
this,
boost::asio::placeholders::error
)
);
ec = writeToServer( *m_SocketPtrClient);
if( ec)
{
// do error handling and throw an exception
}
m_ClientTimeoutDLTPtr->cancel();
//install a timeout handler
m_ClientTimeoutDLTPtr->expires_from_now( boost::posix_time::seconds( m_uiCommTimeout));
m_ClientTimeoutDLTPtr->async_wait( boost::bind( &MyClass::clientTimeoutHandler,
this,
boost::asio::placeholders::error
)
);
ec = readFromServer( *m_SocketPtrClient);
if( ec)
{
// do error handling and throw an exception
}
m_ClientTimeoutDLTPtr->cancel();
void MyClass::clientTimeoutHandler( const boost::system::error_code& ec)
{
if( ec)
{
m_ClientTimeoutDLTPtr->cancel();
m_SocketPtrClient->close();
m_ssMsg << std::endl << "break all handling because of timeout on io_service of Client!";
}
else
{
m_ClientTimeoutDLTPtr->expires_from_now( boost::posix_time::seconds( m_uiCommTimeout));
m_ClientTimeoutDLTPtr->async_wait( boost::bind( &MyClass::clientTimeoutHandler,
this,
boost::asio::placeholders::error
)
);
}
}
我需要连接,写入服务器,然后从服务器获取响应,并且对于每个操作,我都需要超时才能启动。如果我从 io_service 调用 run,那么我无法进行这三个调用。
【问题讨论】:
标签: boost asynchronous boost-asio