Reputation: 2380
I am trying to a set a timeout for a socket that I have created using ASIO in boost with no luck. I have found the following code elsewhere on the site:
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);
The timeout remains at the same 60 seconds as opposed to the 5 seconds I am looking for in the connect call. What am I missing? Note the connect code works fine in all other cases (where there is no timeout).
Upvotes: 0
Views: 1116
Reputation: 9573
The socket options you've set don't apply to connect
AFAIK.
This can be accomplished by using the asynchronous asio API as in the following asio example.
The interesting parts are setting the timeout handler:
deadline_.async_wait(boost::bind(&client::check_deadline, this));
Starting the timer
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();
}
}
And closing the socket which should result in the connect completion handler to run.
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));
}
Upvotes: 1