Skip to content

Instantly share code, notes, and snippets.

@mashiro
Created October 22, 2013 08:26
Show Gist options
  • Save mashiro/7097060 to your computer and use it in GitHub Desktop.
Save mashiro/7097060 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <boost/chrono.hpp>
#include <boost/asio.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/bind.hpp>
namespace asio = boost::asio;
using asio::ip::tcp;
class client
{
public:
client(asio::io_service& io_service)
: socket_(io_service)
, timeout_(io_service)
{}
void start(tcp::resolver::iterator endpoint_iter)
{
start_connect(endpoint_iter);
}
void stop()
{
boost::system::error_code ignored_ec;
socket_.close(ignored_ec);
timeout_.cancel();
}
private:
void start_connect(tcp::resolver::iterator endpoint_iter)
{
if (endpoint_iter == tcp::resolver::iterator())
{
stop();
return;
}
std::cout << "Trying " << endpoint_iter->endpoint() << "..." << std::endl;
timeout_.expires_from_now(boost::chrono::milliseconds(1000));
timeout_.async_wait(boost::bind(&client::on_timeout, this, _1));
boost::asio::async_connect(socket_, endpoint_iter,
[this](const boost::system::error_code& ec, tcp::resolver::iterator endpoint_iter)
{
if (!socket_.is_open())
{
std::cout << "Connect timed out" << std::endl;
start_connect(++endpoint_iter);
}
else if (ec)
{
std::cout << "Connect error: " << ec.message() << std::endl;
socket_.close();
start_connect(++endpoint_iter);
}
else
{
std::cout << "Connected to " << endpoint_iter->endpoint() << std::endl;
timeout_.cancel();
}
});
}
void on_timeout(const boost::system::error_code& ec)
{
if (!ec)
{
std::cout << "Socket cancel" << std::endl;
// socket_.close();
socket_.cancel();
}
}
private:
tcp::socket socket_;
boost::asio::steady_timer timeout_;
};
int main(int argc, char* argv[])
{
try
{
if (argc != 3)
{
std::cerr << "Usage: client <host> <port>" << std::endl;
return 1;
}
boost::asio::io_service io_service;
tcp::resolver r(io_service);
client c(io_service);
c.start(r.resolve(tcp::resolver::query(argv[1], argv[2])));
io_service.run();
}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << std::endl;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment