0

こんにちは、非同期ソケット関数を使用する単純なアプリケーションを 1 つ作成しました。ソケットを閉じているときにいくつかの問題に直面しています。

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

投稿されたコードにはいくつかの異なる問題があるようです。より小さなステップ、つまり次の行に沿って始めることをお勧めします

  • startasio ワーカー スレッドをstopクリーンに (以下の説明を参照)
  • タイマーを開始するコードを追加:OnTimerExpired正しく処理し、エラー コードを確認します
  • のコードを追加しますasync_connect: 接続ハンドラが呼び出されたとき、cancelタイマーとエラー コードを確認します。
  • 他の非同期操作などを追加します。

たとえばcancel、接続ハンドラでタイマーを使用すると、OnTimerExpiredハンドラが呼び出されてからソケットが呼び出されboost::asio::operation_abortedますcloseが、これはおそらくやりたいことではありません。

さらに、あなたはio_service仕事を与えますが、それでも を呼び出しますstop。一般に、io_service に作業を与える場合は、作業を削除して実行スレッドを停止し (たとえば、作業をスマート ポインターに格納してリセットすることで実現できます)、現在開始されている非同期操作を正常に終了させます。

于 2011-12-28T10:37:57.727 に答える