当我调用 boost::asio::io_service::stop() 时,boost::asio::io_service::run() 不退出

发布于 2024-12-22 23:00:51 字数 2185 浏览 1 评论 0原文

您好,我编写了一个使用异步套接字函数的简单应用程序。我在关闭套接字时遇到一些问题。

在调用套接字上的 async_connect 之前,我使用了 5 秒计时器。在某些情况下,连接未发生并且计时器到期。当计时器到期时,我将关闭套接字tcp_socket.close()。但问题是,当我尝试取消而不是关闭时,我的连接回调处理程序根本没有被 boost::asio::error::operation_aborted 错误调用。接下来的所有异步连接调用都会发生同样的事情。

尽管我正在关闭 tcp 套接字并销毁创建的线程上的 client_session 对象 join() 调用没有出来意味着 io_service::run() 仍在运行而不退出...:-( 我不知道为什么这是发生...尝试了很多其他方法仍然面临同样的问题,

我不明白问题是什么,

我的真实代码看起来像这样。

class client_session
{ 
   public:
   client_session(boost::asio::io_service& io_service_ )tcp_socekt_(io_service_),
                                                        timer_(io_service_)
   {
   }

   ~client_session()
   {
       tcp_socket_.close();
   }

   void OnTimerExpired(const boost::system::error_code& err)
   {
      if( err ) tcp_socket_.close();
   }

   //Its just for example this will be called from upper layer of my module. giving some information about the server.
   void connect()
   {
        //Here am starting the timer 
        timer_.expires_from_now(boost::posix_time::seconds(2));
        timer_.async_wait(boost::bind(&OutgoingSession::OnTimerExpiry, this,PLACEHLDRS::error));

        .......

        tcp_socket_.async_connect(iterator->endpoint(), boost::bind( &OutgoingSession::handle_connect, this, _1, iterator));

        ......
   }

   void OnConnect(const boost::system::error_code& err)
   {
      //Cancelling the timer 
      timer_.cancel();
      .....
      //Register for write to send the request to server
      ......
   }

   private:
   tcp::socket tcp_socket_;
   deadline_timer timer_;
} 

void main()
{
  boost::asio::io_service tcp_io_service;
  boost::asio::io_service::work tcp_work(tcp_io_service);

  boost::thread* worker = new boost::thread(&boost::asio::io_service::run,&tcp_io_service);

  client_session* csession = new client_session(tcp_io_service);
  csession->connect();

  sleep(10);

  tcp_io_service.stop();

  delete csession;

  worker.join();    //Here it not coming out of join because io_service::run() is not exited yet.
  cout<<"Termination successfull"<<endl;
}

Hi I having written one simple application which uses the asynchronous socket functions. I am facing some problems while closing the socket.

I am using 5 second timer before calling the async_connect on the socket. In some cases the connection is not happening and timer expires. When timer is expired I am closing the socket tcp_socket.close(). But the thing is my connection callback handler is not at all called with the boost::asio::error::operation_aborted error when i tried to cancel instead of close. The same thing is happening for the next all the async connection invokes.

Eventhough I am closing the tcp socket and destroying the client_session object join() call on the created thread is not coming out means io_service::run() is still running not exiting...:-( I don't know why this is happening... tried lot of other ways still facing the same problem.

I am not getting what is the problem, all suggestions and solutions will be appreciated.

My real code some what look like this.

class client_session
{ 
   public:
   client_session(boost::asio::io_service& io_service_ )tcp_socekt_(io_service_),
                                                        timer_(io_service_)
   {
   }

   ~client_session()
   {
       tcp_socket_.close();
   }

   void OnTimerExpired(const boost::system::error_code& err)
   {
      if( err ) tcp_socket_.close();
   }

   //Its just for example this will be called from upper layer of my module. giving some information about the server.
   void connect()
   {
        //Here am starting the timer 
        timer_.expires_from_now(boost::posix_time::seconds(2));
        timer_.async_wait(boost::bind(&OutgoingSession::OnTimerExpiry, this,PLACEHLDRS::error));

        .......

        tcp_socket_.async_connect(iterator->endpoint(), boost::bind( &OutgoingSession::handle_connect, this, _1, iterator));

        ......
   }

   void OnConnect(const boost::system::error_code& err)
   {
      //Cancelling the timer 
      timer_.cancel();
      .....
      //Register for write to send the request to server
      ......
   }

   private:
   tcp::socket tcp_socket_;
   deadline_timer timer_;
} 

void main()
{
  boost::asio::io_service tcp_io_service;
  boost::asio::io_service::work tcp_work(tcp_io_service);

  boost::thread* worker = new boost::thread(&boost::asio::io_service::run,&tcp_io_service);

  client_session* csession = new client_session(tcp_io_service);
  csession->connect();

  sleep(10);

  tcp_io_service.stop();

  delete csession;

  worker.join();    //Here it not coming out of join because io_service::run() is not exited yet.
  cout<<"Termination successfull"<<endl;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

写给空气的情书 2024-12-29 23:00:51

发布的代码似乎存在一些不同的问题。我建议从较小的步骤开始,即沿着

  • startstop asio 工作线程干净地
  • 添加代码来启动计时器:handle OnTimerExpired< /code> 正确,检查错误代码
  • 添加在async_connect代码中:当调用连接处理程序时,取消计时器并检查错误代码。
  • 添加其他异步操作等。

其中之一是,当您在连接处理程序中取消计时器时,OnTimerExpired 处理程序将通过 boost::asio 调用: :operation_aborted 然后你关闭套接字,这可能不是你想要做的。

此外,您让 io_service 工作,但仍然调用 stop。通常,如果您给 io_service 工作,您希望通过删除工作来停止执行线程(例如,这可以通过将工作存储在智能指针中并重置它来完成)并让当前启动的异步操作干净地完成。

There seem to be a couple of different things wrong with the posted code. I would suggest starting with smaller steps i.e. along the lines of

  • start and stop asio worker thread cleanly ( see explanation below )
  • add code to start timer: handle OnTimerExpired correctly, check error code
  • add in code for async_connect: when connect handler is called, cancel timer and check error code.
  • add in other asynchronous operations, etc.

For one, when you cancel the timer in the connect handler, the OnTimerExpired handler will be invoked with boost::asio::operation_aborted and then you close the socket, which is probably not what you want to do.

Further, you give the io_service work, yet still call stop. Generally if you give the io_service work, you want to stop the execution thread by removing the work (e.g. This can be accomplished by means of storing work in a smart pointer and resetting it) and letting the currently started asynchronous operations finish cleanly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文