2011-03-30 119 views
0

http://www.boost.org/doc/libs/1_46_0/doc/html/boost_asio/example/chat/chat_client.cpp提升客戶端卡住

我正在基於他上面的示例在客戶端應用程序上工作。

我想在separte線程中進行客戶端連接,以便UI不會卡住。這裏的用戶界面正在停滯不前。
1.你能告訴我如何實現這個目標嗎?
2.這條線的含義是什麼? 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);  
} 
} 

回答

0
  1. 你能告訴我該如何實現嗎?

你可以啓動升壓線程在主即你輸入之前的某個地方UI事件循環(阻塞調用),但不做加盟。

查看HTTP服務器示例:在其中一個示例中,它顯示瞭如何在主服務器上啓動io_service並通過CTRL-c停止它。在你的情況下,你可能會使用GUI按鈕或事件來做到這一點。一旦你調用io_service stop方法,你就可以在線程上進行連接。

  1. 這條線的含義是什麼? boost :: thread t(boost :: bind(& boost :: asio :: io_service :: run,& io_service));
  • 運行。該io_service ::在一個新的線程中運行

t.join();

  • 等待線程完成像janm指出,這將發生一次。該io_service耗盡工作或一次。該io_service ::停止方法被調用
2

「t.join()」等待線程't'退出。線程't'在io_service上運行run()方法,並在沒有剩餘的I/O完成時退出。

因此,您的Connect()方法將阻塞,直到所有I/O完成,這不是您想要的。如果您要執行異步I/O以便您的客戶端不會阻塞,則需要爲您的I/O上下文設計一種方式與我們的UI上下文進行通信。它不會發生魔法。

+0

感謝您reply.I正在嘗試做異步I/O.janm可以指導如何做到這一點。我想知道的基本設計,使UI不會卡住。 – 2011-03-30 06:10:48

+0

+1不會因爲魔法而發生。 @Chris基本設計是在你的UI事件循環線程的獨立線程中運行你的io_service。正如詹姆斯所暗示的那樣,你需要爲這兩個線程建立一種溝通方式。如果您有具體問題,請單獨詢問。 – 2011-03-31 00:00:09