• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // 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 <vector>
15 #include "connection.hpp" // Must come before boost/serialization headers.
16 #include <boost/serialization/vector.hpp>
17 #include "stock.hpp"
18 
19 namespace s11n_example {
20 
21 /// Downloads stock quote information from a server.
22 class client
23 {
24 public:
25   /// Constructor starts the asynchronous connect operation.
client(boost::asio::io_context & io_context,const std::string & host,const std::string & service)26   client(boost::asio::io_context& io_context,
27       const std::string& host, const std::string& service)
28     : connection_(io_context.get_executor())
29   {
30     // Resolve the host name into an IP address.
31     boost::asio::ip::tcp::resolver resolver(io_context);
32     boost::asio::ip::tcp::resolver::query query(host, service);
33     boost::asio::ip::tcp::resolver::iterator endpoint_iterator =
34       resolver.resolve(query);
35 
36     // Start an asynchronous connect operation.
37     boost::asio::async_connect(connection_.socket(), endpoint_iterator,
38         boost::bind(&client::handle_connect, this,
39           boost::asio::placeholders::error));
40   }
41 
42   /// Handle completion of a connect operation.
handle_connect(const boost::system::error_code & e)43   void handle_connect(const boost::system::error_code& e)
44   {
45     if (!e)
46     {
47       // Successfully established connection. Start operation to read the list
48       // of stocks. The connection::async_read() function will automatically
49       // decode the data that is read from the underlying socket.
50       connection_.async_read(stocks_,
51           boost::bind(&client::handle_read, this,
52             boost::asio::placeholders::error));
53     }
54     else
55     {
56       // An error occurred. Log it and return. Since we are not starting a new
57       // operation the io_context will run out of work to do and the client will
58       // exit.
59       std::cerr << e.message() << std::endl;
60     }
61   }
62 
63   /// Handle completion of a read operation.
handle_read(const boost::system::error_code & e)64   void handle_read(const boost::system::error_code& e)
65   {
66     if (!e)
67     {
68       // Print out the data that was received.
69       for (std::size_t i = 0; i < stocks_.size(); ++i)
70       {
71         std::cout << "Stock number " << i << "\n";
72         std::cout << "  code: " << stocks_[i].code << "\n";
73         std::cout << "  name: " << stocks_[i].name << "\n";
74         std::cout << "  open_price: " << stocks_[i].open_price << "\n";
75         std::cout << "  high_price: " << stocks_[i].high_price << "\n";
76         std::cout << "  low_price: " << stocks_[i].low_price << "\n";
77         std::cout << "  last_price: " << stocks_[i].last_price << "\n";
78         std::cout << "  buy_price: " << stocks_[i].buy_price << "\n";
79         std::cout << "  buy_quantity: " << stocks_[i].buy_quantity << "\n";
80         std::cout << "  sell_price: " << stocks_[i].sell_price << "\n";
81         std::cout << "  sell_quantity: " << stocks_[i].sell_quantity << "\n";
82       }
83     }
84     else
85     {
86       // An error occurred.
87       std::cerr << e.message() << std::endl;
88     }
89 
90     // Since we are not starting a new operation the io_context will run out of
91     // work to do and the client will exit.
92   }
93 
94 private:
95   /// The connection to the server.
96   connection connection_;
97 
98   /// The data received from the server.
99   std::vector<stock> stocks_;
100 };
101 
102 } // namespace s11n_example
103 
main(int argc,char * argv[])104 int main(int argc, char* argv[])
105 {
106   try
107   {
108     // Check command line arguments.
109     if (argc != 3)
110     {
111       std::cerr << "Usage: client <host> <port>" << std::endl;
112       return 1;
113     }
114 
115     boost::asio::io_context io_context;
116     s11n_example::client client(io_context, argv[1], argv[2]);
117     io_context.run();
118   }
119   catch (std::exception& e)
120   {
121     std::cerr << e.what() << std::endl;
122   }
123 
124   return 0;
125 }
126