提升客户端卡住

时间:2011-03-30 05:23:24

标签: c++ boost boost-asio boost-thread

http://www.boost.org/doc/libs/1_46_0/doc/html/boost_asio/example/chat/chat_client.cpp

我正在根据上面的例子开发客户端应用程序。

我想在separte线程中进行客户端连接,这样UI就不会卡住。这个UI正在陷入困境。
    你能告诉我如何实现这个目标吗?     这条线的含义是什么?         boost :: thread t(boost :: bind(& boost :: asio :: io_service :: run,& io_service));
        t.join();
该行是否为连接创建了单独的线程?

 client::client(boost::asio::io_service& io_service, tcp::resolver::iterator endpoint_iterator)
  : io_service_(io_service),
  resolver_(io_service),
  socket_(io_service_)
{
    tcp::endpoint endpoint = *endpoint_iterator;
    socket_.async_connect(  endpoint,
                                 boost::bind(&client::handle_connect, this,boost::asio::placeholders::error,
                            ++endpoint_iterator));

}
void client::handle_connect(const boost::system::error_code& error,
  tcp::resolver::iterator endpoint_iterator)
{
  strcpy(data_,"Hello");
if (!error)
{
     /*boost::asio::async_read(socket_,
                              boost::asio::buffer(data_, MAX_PATH),
                              boost::bind(&client::handle_read, this,
                              boost::asio::placeholders::error));*/
      boost::asio::async_write(socket_,  boost::asio::buffer(data_, MAX_PATH),
                               boost::bind(&client::handle_read, this,
                            boost::asio::placeholders::error));
}
else if (endpoint_iterator != tcp::resolver::iterator())
{
  socket_.close();
  tcp::endpoint endpoint = *endpoint_iterator;
  socket_.async_connect(    endpoint,
                            boost::bind(&client::handle_connect, this,
                            boost::asio::placeholders::error, ++endpoint_iterator));
}
}

void client::handle_read(const boost::system::error_code& error)
{
if (!error)
{  
     memset(data_,0,MAX_PATH);
     boost::asio::async_read(   socket_,
                                 boost::asio::buffer(data_, MAX_PATH),
                              boost::bind(&client::handle_read, this,
                              boost::asio::placeholders::error));

     if (strcmp(data_,"Hello Response")==0)
     {
         MessageBox(NULL,_T("Regd Done"),_T("Vue"),1);
        // return ;
     }  


}

}

CConnectionMgr::CConnectionMgr(void)
{

}
void CConnectionMgr::Connect()
{
try
{
    char* host = "192.168.4.84";
    char* port = "55555";
    boost::asio::io_service io_service;

    tcp::resolver resolver(io_service);
    tcp::resolver::query query(tcp::v4(),host , port);
    tcp::resolver::iterator iterator = resolver.resolve(query);

    c = new client(io_service, iterator);

    //boost::thread thrd(boost::bind(&boost::asio::io_service::run, &io_service));
    boost::thread t(boost::bind(&boost::asio::io_service::run, &io_service));
    t.join();
    // MessageBox(NULL,_T("Join"),_T("ff"),1);
}
catch (std::exception& e)
{
  CString csMsg(e.what());
  MessageBox(NULL,csMsg,_T("ff"),1);    
 }
 }

2 个答案:

答案 0 :(得分:2)

“t.join()”等待线程't'退出。线程't'正在运行io_service上的run()方法,并且在没有剩余的I / O完成时将退出。

因此,您的Connect()方法将阻塞,直到所有I / O完成,这显然不是您想要的。如果要进行异步I / O以便客户端不会阻塞,则需要为I / O上下文设计一种与UI上下文进行通信的方法。魔术不会发生这种情况。

答案 1 :(得分:0)

  
      
  1. 你能告诉我如何实现这个目标吗?
  2.   

您可以在进入UI事件循环(阻止调用)之前在主要地方启动提升线程,但不要进行连接。

查看HTTP服务器示例:在其中一个示例中,它显示了如何在main中启动io_service并通过CTRL-c停止它。在您的情况下,您可能会使用GUI按钮或事件来执行此操作。一旦调用了io_service stop方法,就可以在线程上进行连接。

  
      
  1. 这条线的意思是什么? boost :: thread t(boost :: bind(& boost :: asio :: io_service :: run,& io_service));
  2.   
  • 在新线程中运行io_service :: run
  

t.join();

  • 等待线程完成就像janm所述,一旦io_service失效或一旦调用io_service :: stop方法就会发生