Boost Client застрять - PullRequest
       29

Boost Client застрять

0 голосов
/ 30 марта 2011

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

Я работаю над клиентским приложением на основе приведенного выше примера.

Я хотел установить клиентское соединение в отдельном потоке, чтобы пользовательский интерфейс не зависал. Вот пользовательский интерфейс застрял.
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);    
 }
 }

Ответы [ 2 ]

2 голосов
/ 30 марта 2011

Функция "t.join ()" ожидает завершения потока 't'.Поток 't' запускает метод run () в io_service и завершает свою работу, когда не осталось оставшихся операций ввода-вывода.

Итак, ваш метод Connect () будет блокироваться до тех пор, пока все операции ввода-вывода не будут завершены.что понятно не то что ты хочешь.Если вы собираетесь выполнять асинхронный ввод-вывод, чтобы ваш клиент не блокировал, вам необходимо разработать способ взаимодействия контекста ввода-вывода с нашим контекстом пользовательского интерфейса.Это не произойдет по волшебству.

0 голосов
/ 30 марта 2011
  1. Можете ли вы сказать мне, как этого добиться?

Вы можете запустить поток повышения в главном, т. Е. Где-то перед тем, как войти в цикл событий пользовательского интерфейса (блокирующий вызов), но не выполнять соединение.

Посмотрите примеры HTTP-сервера: в одном из них показано, как вы можете запустить свой io_service в главном и остановить его с помощью CTRL-c. В вашем случае вы, вероятно, сделали бы это, используя кнопку GUI или событие. После вызова метода остановки io_service вы можете выполнить соединение в потоке.

  1. в чем смысл этой строки? boost :: thread t (boost :: bind (& boost :: asio :: io_service :: run, & io_service));
  • Запускает io_service :: run в новом потоке
* * T.join тысячи двадцать-одина (); * * 1 022
  • Ожидает завершения потока, как указано в janm, что произойдет, когда io_service завершит работу или когда будет вызван метод io_service :: stop
...