2016-10-31 1 views
0

Я новичок в network, tcp & sockets programming. Я использую boost::asio в своем приложении для передачи данных по wifi по протоколу tcp/ip. Данные отправляются еще одним приложением, которое работает на главной машине, чей ip & порт известен моему приложению во время запуска. И приложение подключается к этому HostApp для извлечения данных во время выполнения.повышения :: ASIO :: io_service.run() занимает много времени, чтобы вернуться, когда деталь хоста действительна, но на стороне сервера приложения не работают

Ниже приведен фрагмент кода в мое приложение, которое подключается к хосту:

std::shared_ptr<tcp::resolver> resolver = std::make_shared<tcp::resolver>(io_service); 
tcp::resolver::query tcp_query(IP_Address, Port_Number); 
boost::system::error_code host_resolve_error; 
tcp::resolver::iterator destination = resolver->resolve(tcp_query, host_resolve_error); 
socket.reset(new tcp::socket(io_service)); 

if (host_resolve_error) { 
    std::cout << "IP & port inputted could not be resolved" << std::endl; 
    return false; 
} 

auto connection_state_callback_handler = [this] 
     (const boost::system::error_code& error_code, const tcp::resolver::iterator& it) 
{ 
    if (error_code){ 
     //Error has occurred. Abort or retry 
     connection_set = false; 
    } 
    else { 
     if (it == tcp::resolver::iterator()) { 
     //Some logic 
     connection_set = false; 
     } 
     else { 
     connection_set = true; 
     std::cout << "Callback received for socket connected" << std::endl; 

     //Small test to check my data header to confirm that connection is set 
     MyDataHeader data_head; 
     boost::asio::read(*m_socket, boost::asio::buffer(& data_head, sizeof(data_head))); 
    } 
    } 
}; 
//call boost asynchronous connect passing it a handler as it needs to report back when ready 
boost::asio::async_connect(*m_socket, destination, tcp::resolver::iterator(), connection_state_callback_handler); 

io_service.run(); //Takes long time to return when HostApp is not running 
StartMyDataThread_WhichPollsData_InALoop(); 

Приведенный выше код подключается быстро & отлично работает каждый раз, когда ip & port правильность ввода плюс HostApp работает. Если я ввожу неправильный/нерешаемый ip + порт, тогда host_resolve_error получает значение & Я возвращаюсь мгновенно. Благодаря следующему блоку.

if (host_resolve_error) { 
    std::cout << "IP & port inputted could not be resolved" << std::endl; 
    return false; 
} 

Но вот проблема я столкнулся: Когда ip & port введен действительный один плюс мой HostApp не работает на стороне сервера, то io_service.run() занимает много времени, как 20-30 секунд, чтобы вернуться , И это вредно для моего приложения.

Есть ли какой-либо другой API из io_service где может установить time_out & получить такую ​​же функциональность как io_service.run()? Или какой-то другой способ быстро решить, что мой HostApp не работает?

Я попытался довольно некоторые вещи, чтобы попытаться постановляю:
1. Я попытался передать io_service.run() в std::async, как показано ниже, но не работает

auto handle = std::async(std::launch::async, [this]{ io_service.run(); }); 

2. Я пытался позвонить io_service.run_one() вместо io_service.run(). Это также требует времени для возврата

Каков наилучший способ решить эту проблему? Мне нужно вернуть io_service.run(), даже если он не смог установить соединение. Как добавить механизм time_out в io_service.run()?

+0

вы не можете сказать, если целевая машина вниз, соединение имеет тайм-аут. Единственное, что вы можете сделать, это сократить таймаут – pm100

+0

Согласен. Но мой вопрос заключается в том, как добавить этот time_out в этот код, который я выставил? –

+0

Хорошо. Обновлен мой вопрос. Я ищу способ добавить 'time_out' в' io_service.run() ', но я не знаю, как это сделать.Борясь, чтобы понять это –

ответ

0

Вы просто добавляете экземпляр io_service в таймер окончания в конструкторе. Так импортировать <boost/asio/deadline_timer.hpp> и построить свой io_service как:

client(boost::asio::io_service& io_service) 
    : stopped_(false), 
     socket_(io_service), 
     deadline_(io_service), 
     heartbeat_timer_(io_service) 
    { 
    } 

Тогда вы можете назвать это позже в коде, как:

deadline_.expires_from_now(boost::posix_time::seconds(60)); 
+0

Спасибо за внимание. как я могу использовать этот 'deadline_.expires_from_now' с' io_service.run'. Вызовите его непосредственно перед вызовом 'io_service.run'? –

+0

Как я понимаю, я передаю этот 'deadline_' только в функцию' async_connect'. Не в 'io_service.run'. –

+1

Да, если вы выполняете асинхронные операции. Вы также можете заблокировать соединение. – mutantkeyboard

Смежные вопросы