1

私の質問では。私はクライアントであり、私の目的は、毎回ではなく、必要なときにいつでもサーバーで書き込むことだけです。

1つのシングルトンクラス(Callerクラス)があり、クライアントプログラム(Client)を呼び出してサーバーにメッセージを書き込み、boost :: asio :: io_service::runを1​​つのスレッドで呼び出します。私のクライアントプログラム(Client)もシングルトンクラスです。

サーバーがすでに実行されている場合、私のプログラムは正常に動作します。クライアントは最初にサーバーに接続するためです。しかし、サーバーが再起動するか実行されていない場合は、メッセージを書き込む前に、サーバーが実行されているかどうかを確認する必要があります。

サーバーが使用可能かどうかを毎回確認するには、Caller :: run()を呼び出してio_serviceを実行する必要があります。

プログラムですべての同期を使用しているため、io_serviceを実行しないと、サーバーが実行されているかどうかを確認できません。すべてが非同期になっています(asycn connect、sync write)

私の問題は、プログラムが+ D1状態(中断できないスリープ)になり、プログラムを閉じることができない場合があることです。これはio_service()によるものですか?

io_serviceを実行せずにサーバーがオンになっているかどうかを確認するにはどうすればよいですか?

 class Caller
 {
  public:

  static Caller* getInstance()
  {
   static Caller Caller;
   return &Caller;
  }

  void run() 
  {
    pWork.reset( new boost::asio::io_service::work(io_service) );

    ////////////calling client program//////////////// 
    Client::getInstance(io_service)->start();

    thread = boost::thread(boost::bind(&boost::asio::io_service::run, &io_service));
  }     

  boost::asio::io_service io_service;
  boost::shared_ptr<boost::asio::io_service::work> pWork;

  boost::thread thread;

 private:
  Caller()
  {
  }
  ~Caller()
  {
    pWork.reset();
    thread.join();
  }
}; 


///////////my client program (Singleton Class)//////////////////
//////message write function///////////

void Client::sendResponse(std::string& messag)                      
{                                                                              
  boost::system::error_code error;                                           
  boost::asio::ip::tcp::endpoint endpoint = socket().remote_endpoint(error);    

  if ( error ) 
  {                                                               
    DEBUG_2("could not write: ",boost::system::system_error(error).what());    
    this->stop(); /////this will close the socket////
    Caller::getInstance()->run();   
    //////it will call the caller program to call the  connect function of client program /////
  }                                                                           
  else
    boost::asio::async_write(                                                         
      _socket,                                                                      
      boost::asio::buffer( message.c_str(), message.size()),
      _strand.wrap(                                                                 
        boost::bind(                                                                
          &Client::writeHandler,                                             
          this,
          boost::asio::placeholders::error,                                         
          boost::asio::placeholders::bytes_transferred  
}                                                                              


 Client *Client::getInstance(boost::asio::io_service& io_service)
  {
    if (!Client)
    {
      Client = new Client(io_service);
    }
    return Client;
  } 

サーバーに書き込むだけで、io_serviceを何度も実行する必要がないように設計できますか?または、io_service :: reset()を呼び出す必要がありますか?正しい方法で作業を使用していますか?

これを適切に停止または中止するにはどうすればよいですか?io_servie :: stopを呼び出すか、このスレッドに参加しますか?

4

1 に答える 1

1

接続の有効性を検出するための一般的な方法は、async_read()接続に成功した後に実行することです。async_read()コールバックがエラーを示した場合boost::asio::error::eof、アプリケーションは適切に反応する必要があります。

  1. おそらくタイムアウト遅延で再接続します
  2. 正常に終了する
  3. アボート

オプション#1が必要なようです。正しく記述されている場合、アプリケーションは1回だけ呼び出す必要がありio_service::run()、イベントループは常に実行する必要があります。


クロージャを検出するためにソケットから読み取りたくない場合は、workオブジェクトをインスタンス化し、プログラムの期間中、スコープ内に保持します。io_serviceこれにより、常にやるべきことが確実になります。async_write完了ハンドラーがエラーで呼び出された場合は、前に提案したように、アプリケーションに対して必要に応じて対応します。

于 2013-03-14T04:31:14.213 に答える