2013-03-12 42 views
1

在我的问题。我是一个客户,我的目的只是在服务器上写任何时候都不需要每次。我有一个单一的类(调用者类),我叫我的客户端程序(客户端)写服务器上的任何消息和 ,然后通过一个线程调用boost :: asio :: io_service :: run。我的客户端程序(客户端)也是单例类。问题与ASIO io_service多次运行

如果服务器已在运行,我的程序工作正常。因为客户端将首先连接到服务器。但是,如果服务器重新启动或不运行,那么在写消息之前,我必须检查服务器是否正在运行。

要检查每次是否可用服务器,我必须调用Caller :: run()并运行io_service。

没有运行io_service我无法检查服务器是否正在运行,因为我正在使用我的程序中的所有同步。 一切都在异步(asycn连接,同步写入)

我的问题是,有时我的程序进入+ 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或加入此线程?

回答

1

检测连接有效性的典型方法是在连接成功后执行async_read()。当async_read()回调指示boost::asio::error::eof错误,应用程序应作出适当的反应:

  1. 重新连接,或许还有一个超时延迟
  2. 终止正常
  3. 中止

这听起来像你需要选择#1 。如果编写正确,您的应用程序只需要调用io_service::run()一次,事件循环将不断有工作要做。


如果你不想从套接字读取检测关闭,实例化一个work对象,并保持它的范围为程序的持续时间。这将确保io_service总是有工作要做。当您的async_write完成处理程序被调用时发生错误,根据需要为您的应用程序做出反应,如前所述。

+0

1.我不能使用async_read,因为我不需要从服务器读取数据。 2.如果服务器没有打开,那么无论何时客户端需要在服务器上写入任何消息,客户端都会尝试连接到服务器,因此超时延迟是不可能的。 3.请让我知道我该如何优雅地终止? 通过调用io_service :: stop或加入此线程? 4.如何中止? – user1841046 2013-03-15 10:21:29

+0

@ user1841046答案已编辑,以解决您的意见 – 2013-03-15 15:03:37

+0

感谢您的帮助。 这意味着我只需要保持范围内的io_service和每当我需要重新连接我只需要调用启动函数从函数Client :: sendResponse(std :: string&message)连接到服务器。不需要再次运行io_service。 和它工作正常。 谢谢 – user1841046 2013-03-16 07:59:56

相关问题