• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // daytime_client.cpp
3 // ~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10 
11 #include <boost/asio.hpp>
12 #include <boost/bind/bind.hpp>
13 #include <iostream>
14 #include "logger.hpp"
15 
16 using boost::asio::ip::tcp;
17 
18 char read_buffer[1024];
19 
read_handler(const boost::system::error_code & e,std::size_t bytes_transferred,tcp::socket * s)20 void read_handler(const boost::system::error_code& e,
21     std::size_t bytes_transferred, tcp::socket* s)
22 {
23   if (!e)
24   {
25     std::cout.write(read_buffer, bytes_transferred);
26 
27     s->async_read_some(boost::asio::buffer(read_buffer),
28         boost::bind(read_handler, boost::asio::placeholders::error,
29           boost::asio::placeholders::bytes_transferred, s));
30   }
31   else
32   {
33     boost::asio::execution_context& context = boost::asio::query(
34         s->get_executor(), boost::asio::execution::context);
35     services::logger logger(context, "read_handler");
36 
37     std::string msg = "Read error: ";
38     msg += e.message();
39     logger.log(msg);
40   }
41 }
42 
connect_handler(const boost::system::error_code & e,tcp::socket * s)43 void connect_handler(const boost::system::error_code& e, tcp::socket* s)
44 {
45   boost::asio::execution_context& context = boost::asio::query(
46       s->get_executor(), boost::asio::execution::context);
47   services::logger logger(context, "connect_handler");
48 
49   if (!e)
50   {
51     logger.log("Connection established");
52 
53     s->async_read_some(boost::asio::buffer(read_buffer),
54         boost::bind(read_handler, boost::asio::placeholders::error,
55           boost::asio::placeholders::bytes_transferred, s));
56   }
57   else
58   {
59     std::string msg = "Unable to establish connection: ";
60     msg += e.message();
61     logger.log(msg);
62   }
63 }
64 
main(int argc,char * argv[])65 int main(int argc, char* argv[])
66 {
67   try
68   {
69     if (argc != 2)
70     {
71       std::cerr << "Usage: daytime_client <host>" << std::endl;
72       return 1;
73     }
74 
75     boost::asio::io_context io_context;
76 
77     // Set the name of the file that all logger instances will use.
78     services::logger logger(io_context, "");
79     logger.use_file("log.txt");
80 
81     // Resolve the address corresponding to the given host.
82     tcp::resolver resolver(io_context);
83     tcp::resolver::results_type endpoints =
84       resolver.resolve(argv[1], "daytime");
85 
86     // Start an asynchronous connect.
87     tcp::socket socket(io_context);
88     boost::asio::async_connect(socket, endpoints,
89         boost::bind(connect_handler,
90           boost::asio::placeholders::error, &socket));
91 
92     // Run the io_context until all operations have finished.
93     io_context.run();
94   }
95   catch (std::exception& e)
96   {
97     std::cerr << e.what() << std::endl;
98   }
99 
100   return 0;
101 }
102