#define BOOST_ASIO_ENABLE_CANCELIO
#include <iostream>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/optional.hpp>
#include <boost/function.hpp>
#include <boost/system/error_code.hpp>
#include <boost/system/system_error.hpp>
template <class Stream>
void cancel_reading(Stream* stream, bool* timeout, boost::system::error_code e)
{
std::cout << "cancel_reading: stream(" << stream << ") timeout(" << timeout << ") error_code(" << std::dec << e << ")" << std::endl;
if(e != boost::asio::error::operation_aborted)
{
stream->cancel();
*timeout = true;
}
}
void read_finished(boost::asio::deadline_timer* timer, boost::system::error_code e, std::size_t bytes_transferred)
{
std::cout << "read_finished: timer(" << timer << ") error_code(" << e << ") bytes_transferred(" << bytes_transferred << ")" << std::endl;
timer->cancel();
if(e && e != boost::asio::error::operation_aborted)
throw boost::system::system_error(e);
}
template <class Stream>
void timed_read(Stream& stream, std::vector<char>& buf, unsigned ms)
{
bool timeout = false;
boost::asio::deadline_timer timer(stream.io_service());
std::cout << "timed_read: stream(" << &stream << ") timer(" << &timer << ") timeout(" << &timeout << ")" << std::endl;
timer.expires_from_now(boost::posix_time::milliseconds(ms));
timer.async_wait(boost::bind(cancel_reading<Stream>, &stream, &timeout, _1));
boost::asio::async_read(stream, boost::asio::buffer(buf), boost::bind(read_finished, &timer, _1, _2));
stream.io_service().reset();
stream.io_service().run();
std::cout << "read " << (timeout ? "with" : "without") << " timeout" << std::endl;
}
int main()
{
#define TEST_SERIAL
try
{
boost::asio::io_service io;
#ifdef TEST_SERIAL
std::string com = "COM1";
boost::asio::serial_port stream(io);
boost::system::error_code ec;
if(stream.open(com, ec))
{
std::cout << "cannot open " << com << std::endl;
return EXIT_FAILURE;
}
typedef boost::asio::serial_port options;
stream.set_option(options::baud_rate(115200));
stream.set_option(options::flow_control(options::flow_control::none));
stream.set_option(options::parity(options::parity::none));
stream.set_option(options::stop_bits(options::stop_bits::one));
stream.set_option(options::character_size(CHAR_BIT));
stream.write_some(boost::asio::buffer("zzzzzz"));
#else
std::string host = "www.google.com";
std::string port = "80";
boost::asio::ip::tcp::resolver resolver(io);
boost::asio::ip::tcp::resolver::query query(boost::asio::ip::tcp::v4(), host, port);
boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
boost::asio::ip::tcp::socket stream(io);
stream.connect(*iterator);
#endif
std::vector<char> buf(100);
timed_read(stream, buf, 3000);
stream.close();
return EXIT_SUCCESS;
}
catch(const std::exception& e)
{
std::cout << e.what() << std::endl;
}
}