Я пытаюсь установить тайм-аут для сокета, который я создал с помощью ASIO в boost без везения. Я нашел следующий код в другом месте на сайте:
tcp::socket socket(io_service);
struct timeval tv;
tv.tv_sec = 5;
tv.tv_usec = 0;
setsockopt(socket.native(), SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
setsockopt(socket.native(), SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
boost::asio::connect(socket, endpoint_iterator);
Таймаут остается за 60 секунд, а не 5 секунд, которые я ищу в вызове соединения. Что мне не хватает? Обратите внимание, что код подключения отлично работает во всех остальных случаях (когда нет таймаута).
Параметры сокета, которые вы установили, не применяются для connect
AFAIK. Это может быть выполнено с использованием асинхронного API asio, как в следующем примере asio.
Интересные части устанавливают обработчик тайм-аута:
deadline_.async_wait(boost::bind(&client::check_deadline, this));
Запуск таймера
void start_connect(tcp::resolver::iterator endpoint_iter)
{
if (endpoint_iter != tcp::resolver::iterator())
{
std::cout << "Trying " << endpoint_iter->endpoint() << "...\n";
// Set a deadline for the connect operation.
deadline_.expires_from_now(boost::posix_time::seconds(60));
// Start the asynchronous connect operation.
socket_.async_connect(endpoint_iter->endpoint(),
boost::bind(&client::handle_connect,
this, _1, endpoint_iter));
}
else
{
// There are no more endpoints to try. Shut down the client.
stop();
}
}
И закрытие сокета, которое должно привести к выполнению обработчика завершения соединения.
void check_deadline()
{
if (stopped_)
return;
// Check whether the deadline has passed. We compare the deadline against
// the current time since a new asynchronous operation may have moved the
// deadline before this actor had a chance to run.
if (deadline_.expires_at() <= deadline_timer::traits_type::now())
{
// The deadline has passed. The socket is closed so that any outstanding
// asynchronous operations are cancelled.
socket_.close();
// There is no longer an active deadline. The expiry is set to positive
// infinity so that the actor takes no action until a new deadline is set.
deadline_.expires_at(boost::posix_time::pos_infin);
}
// Put the actor back to sleep.
deadline_.async_wait(boost::bind(&client::check_deadline, this));
}