C++ boost::asio io_服务不';停止后不返回()
我正在开发一个应用程序,它使用boost::asio在不同端口上侦听TCP和UDP数据包。我通过使用与asio教程示例中类似的服务器类来实现这一点,并将它们全部指向一个io_服务 因此,总体而言,我的主要功能(win32控制台应用程序)如下所示:C++ boost::asio io_服务不';停止后不返回(),c++,boost,boost-asio,C++,Boost,Boost Asio,我正在开发一个应用程序,它使用boost::asio在不同端口上侦听TCP和UDP数据包。我通过使用与asio教程示例中类似的服务器类来实现这一点,并将它们全部指向一个io_服务 因此,总体而言,我的主要功能(win32控制台应用程序)如下所示: int main(int argc, char* argv[]) { //some initializations here try { asio::io_service io_service;
int main(int argc, char* argv[])
{
//some initializations here
try
{
asio::io_service io_service;
TcpServer ServerTCP_1(io_service, /*port number here*/);
TcpServer ServerTCP_2(io_service, /*port number here*/);
UdpServer ServerUDP(io_service, /*port number here*/);
io_service.run();
}
catch(std::exception& e)
{
std::cerr << e.what() << std::endl;
}
//cleanup code here
return 0;
}
现在,由于我有3个不同的服务器对象,他应该关闭它们的所有接收器,让io_服务
不工作,这会再次导致io_服务
从run()
调用返回,这会使程序进入主函数中的清理代码,对吗?
除此之外,printf
调用还应该执行3次,或者
首先,io\u服务
不会返回,清理代码永远不会到达。
其次,控制台中最多只显示一个printf调用
第三,通过调试,我发现当我退出程序时,handle\u stop()
另一件可能值得一提的事情是,程序在关闭后不会返回0,而是返回0(线程的数量不同):
因此,我想知道为什么会发生这种情况,我如何修复它,以及如何正确地获取清理代码?由于io\u服务中总是有工作,因此io\u服务将永远不会返回。调用时,接受器的异步接受操作将立即取消。这些已取消操作的处理程序将被传递boost::asio::error::operation\u aborted
错误
在当前代码中,问题是始终启动新的异步接受操作的结果,即使接受程序
已关闭。因此,工作总是被添加到io\u服务中
void start_accept(){
// If the acceptor is closed, handle_accept will be ready to run with an
// error.
acceptor_.async_accept(..., handle_accept);
}
void handle_accept(const system::error_code& error){
if(!error)
{
connection->start();
}
// Always starts a new async accept operation, even if the acceptor
// has closed.
start_accept();
}
void handle_stop(){
acceptor_.close();
}
Boost.Asio示例通过检查handle\u accept
调用中是否关闭了acceptor\u
来防止这种情况发生。如果acceptor\u
不再打开,则处理程序将提前返回,而不会向io\u服务添加更多工作
void start_accept(){
// If the acceptor is closed, handle_accept will be ready to run with an
// error.
acceptor_.async_accept(..., handle_accept);
}
void handle_accept(const system::error_code& error){
if(!error)
{
connection->start();
}
// Always starts a new async accept operation, even if the acceptor
// has closed.
start_accept();
}
void handle_stop(){
acceptor_.close();
}
以下是示例中的相关片段:
为了澄清,您是否如问题标题中所建议的那样致电?此外,可能值得发布更多代码,因为问题似乎在其他地方。我以前在handle_stop中使用过它,但1)它也没有效果(io_服务没有返回),2)我将其更改为acceptor_u.close(),因为在一些boost示例中也使用了它。还有,你会推荐什么代码,或者你对什么代码感兴趣,我不确定如果我用我所有的代码垃圾发布这个主题会有什么好处;)服务器析构函数、接受调用和处理程序可以提供一些细节。如果未返回io\u service::run()
,则不会调用每个信号集的处理程序,并且catch不会打印异常,然后它通常表示某个地方发生了阻塞调用。我更新了我的帖子,实际上我没有自定义析构函数,因为我在boost示例中也没有看到任何析构函数。这听起来不错,但即使在这些更改之后,io_服务仍然没有返回。当我尝试调试调用handle_stop()时发生的事情时,整个程序在调用acceptor_u.close()或printf()后退出(与我上面描述的问题相同)。出于测试目的,我只使用了一个服务器对象,但问题仍然存在,即使没有发生任何事情(没有连接客户端)。据我所知,在调用acceptor_979;.close()时,也不会调用处理程序。@user2047610:听起来好像在调用未发布的代码中未定义的行为。基于这些调用,我建议验证TcpConnection
实例是否比它绑定到的所有处理程序都长。确保它是从enable\u shared\u from\u this
公开继承的,并且实例是通过boost::bind
从
而不是shared\u this
绑定到具有shared\u from\u this()的处理程序的。但是当我这样做时,他抛出了一个异常“tr1::bad\u弱\u ptr”,可能是因为使用了\u this()的shared\u在TcpServer构造函数中设置的信号\u的异步调用中,如何解决此问题?@user2047610:shared\u from\u this()
不能在调用它的类的构造函数中使用。例如,不应从TcpConnection
的构造函数中调用this()
中的shared\u。考虑一下如何在HTTP Server 1类中使用<代码> SydRyFasBy()/<代码>。好吧,出于好奇,我花了时间编译HTTP示例1和3(从示例中取出代码1:1),同样的问题发生了!io_服务不返回,并且在退出时返回相同的代码(-1073741510(0xc000013a))。这让我想到一个问题,这是否可能是一个更深层次的问题?我正在使用64位Windows 7,并使用Visual Studio 2010进行编译和调试。
void start_accept(){
// If the acceptor is closed, handle_accept will be ready to run with an
// error.
acceptor_.async_accept(..., handle_accept);
}
void handle_accept(const system::error_code& error){
if(!error)
{
connection->start();
}
// Always starts a new async accept operation, even if the acceptor
// has closed.
start_accept();
}
void handle_stop(){
acceptor_.close();
}
void server::handle_accept(const boost::system::error_code& e)
{
// Check whether the server was stopped by a signal before this completion
// handler had a chance to run.
if (!acceptor_.is_open())
{
return;
}
if (!e)
{
connection_manager_.start(new_connection_);
}
start_accept();
}