Guest User

NetworkClient

a guest
Sep 25th, 2019
298
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. class NetworkClient
  2. {
  3. public:
  4.     NetworkClient(const std::string &host, const std::string &port);
  5.     NetworkClient(const NetworkClient&) = delete;
  6.     NetworkClient& operator=(const NetworkClient&) = delete;
  7.     ~NetworkClient();
  8.  
  9.     void connect();
  10.     void disconnect();
  11.  
  12.     int write(const uint8_t *buffer, std::size_t size);
  13.     int write(const std::string &buffer);
  14.  
  15.     int wait(std::chrono::steady_clock::duration timeout);
  16.     int available();
  17.     int read_some(uint8_t *buffer, std::size_t size);
  18.     int read_some_wait(uint8_t *buffer, std::size_t size);
  19.     int read_exactly(uint8_t *buffer, std::size_t size, std::chrono::steady_clock::duration timeout);
  20.     int read_until(std::string &buffer, char delim, std::chrono::steady_clock::duration timeout);
  21.  
  22.     operator bool() const { return connected; }
  23.     bool is_connected() const { return connected; }
  24.  
  25.     std::string get_host() const { return host; }
  26.     std::string get_port() const { return port; }
  27.  
  28. protected:
  29.     bool connected = false;
  30.     std::string host;
  31.     std::string port;
  32.  
  33.     std::shared_ptr<boost::asio::io_context> io_context;
  34.     std::unique_ptr<boost::asio::ip::tcp::resolver> resolver;
  35.     std::unique_ptr<boost::asio::ip::tcp::socket> socket;
  36.  
  37.     bool run_for(std::chrono::steady_clock::duration timeout); /// Run operation with timeout
  38.     bool run_until(const std::chrono::steady_clock::time_point &timepoint); /// Run operation until timepoint
  39. };
  40.  
  41. NetworkClient::NetworkClient(const std::string &host, const std::string &port): host(host), port(port)
  42. {
  43.     connect();
  44. }
  45.  
  46. NetworkClient::~NetworkClient()
  47. {
  48.     if (connected) {
  49.         disconnect();
  50.     }
  51. }
  52.  
  53. void NetworkClient::connect()
  54. {
  55.     io_context = std::make_shared<boost::asio::io_context>();
  56.     resolver = std::make_unique<boost::asio::ip::tcp::resolver>(*io_context);
  57.     socket = std::make_unique<boost::asio::ip::tcp::socket>(*io_context);
  58.     boost::system::error_code ec;
  59.     boost::asio::connect(*socket, resolver->resolve(host, port, ec), ec);
  60.     if (ec)
  61.         connected = false;
  62.     else
  63.         connected = true;
  64. }
  65.  
  66. void NetworkClient::disconnect()
  67. {
  68.     boost::system::error_code ec;
  69.     socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
  70.     socket->close(ec);
  71.     io_context->stop();
  72.     connected = false;
  73. }
  74.  
  75. int NetworkClient::write(const uint8_t *buffer, std::size_t size)
  76. {
  77.     boost::system::error_code ec;
  78.     size_t length = boost::asio::write(*socket, boost::asio::buffer(buffer, size), ec);
  79.     if (ec)
  80.         return -1;
  81.     return length;
  82. }
  83.  
  84. int NetworkClient::write(const std::string &buffer)
  85. {
  86.     return write(reinterpret_cast<const uint8_t *>(buffer.c_str()), buffer.size() + 1);
  87. }
  88.  
  89. int NetworkClient::wait(std::chrono::steady_clock::duration timeout)
  90. {
  91.     boost::system::error_code ec;
  92.     socket->async_wait(boost::asio::ip::tcp::socket::wait_read,
  93.                        [&](const boost::system::error_code& result_error)
  94.                        {
  95.                            ec = result_error;
  96.                        });
  97.     bool timedout = run_for(timeout);
  98.     if (ec || timedout)
  99.         return -1;
  100.     return 0;
  101. }
  102.  
  103. int NetworkClient::available()
  104. {
  105.     boost::system::error_code ec;
  106.     std::size_t available = socket->available(ec);
  107.     if (ec)
  108.         return -1;
  109.     return available;
  110. }
  111.  
  112. int NetworkClient::read_some(uint8_t *buffer, std::size_t size)
  113. {
  114.     boost::system::error_code ec;
  115.     std::size_t available = socket->available(ec);
  116.     if (ec)
  117.         return -1;
  118.  
  119.     if (available > 0) {
  120.         if (available > size)
  121.             available = size;
  122.         std::size_t length = boost::asio::read(*socket, boost::asio::buffer(buffer, available), ec);
  123.         if (ec)
  124.             return -1;
  125.         return length;
  126.     }
  127.     return 0;
  128. }
  129.  
  130. int NetworkClient::read_some_wait(uint8_t *buffer, std::size_t size)
  131. {
  132.     boost::system::error_code ec;
  133.  
  134.     std::size_t length = socket->read_some(boost::asio::buffer(buffer, size), ec);
  135.     if (ec)
  136.         return -1;
  137.     return length;
  138. }
  139.  
  140. int NetworkClient::read_exactly(uint8_t *buffer, std::size_t size, std::chrono::steady_clock::duration timeout)
  141. {
  142.     boost::system::error_code ec;
  143.     std::size_t n = 0;
  144.     boost::asio::async_read(*socket, boost::asio::buffer(buffer, size),
  145.                             [&](const boost::system::error_code& result_error, std::size_t result_n)
  146.                             {
  147.                                 ec = result_error;
  148.                                 n = result_n;
  149.                             });
  150.  
  151.     bool timedout = run_for(timeout);
  152.  
  153.     if (!timedout && ec)
  154.         return -1;
  155.     return n;
  156. }
  157.  
  158. int NetworkClient::read_until(std::string &buffer, char delim, std::chrono::steady_clock::duration timeout)
  159. {
  160.     boost::system::error_code ec;
  161.     std::size_t n = 0;
  162.     boost::asio::async_read_until(*socket, boost::asio::dynamic_buffer(buffer), delim,
  163.                                   [&](const boost::system::error_code& result_error, std::size_t result_n)
  164.                                   {
  165.                                       ec = result_error;
  166.                                       n = result_n;
  167.                                   });
  168.  
  169.     bool timedout = run_for(timeout);
  170.  
  171.     if (!timedout && ec)
  172.         return -1;
  173.     return n;
  174. }
  175.  
  176. bool NetworkClient::run_for(std::chrono::steady_clock::duration timeout)
  177. {
  178.     io_context->restart();
  179.     io_context->run_for(timeout);
  180.  
  181.     if (!io_context->stopped()) {
  182.         socket->cancel(); // close()
  183.         io_context->run();
  184.         return true;
  185.     }
  186.  
  187.     return false;
  188. }
  189.  
  190. bool NetworkClient::run_until(const std::chrono::steady_clock::time_point &timepoint)
  191. {
  192.     io_context->restart();
  193.     io_context->run_until(timepoint);
  194.  
  195.     if (!io_context->stopped()) {
  196.         socket->cancel();
  197.         io_context->run();
  198.         return true;
  199.     }
  200.  
  201.     return false;
  202. }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×