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