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;
}
4

1 回答 1

1

发布的代码似乎有几个不同的问题。我建议从较小的步骤开始,即沿着

  • startstop干净的 asio 工作线程(参见下面的解释)
  • 添加代码以启动计时器:OnTimerExpired正确处理,检查错误代码
  • 添加代码async_connect:当调用连接处理程序时,cancel计时器并检查错误代码。
  • 添加其他异步操作等

一方面,当您cancel在连接处理程序中设置计时器时,OnTimerExpired将调用处理程序,boost::asio::operation_aborted然后调用close套接字,这可能不是您想要做的。

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

于 2011-12-28T10:37:57.727 回答