server.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. //
  2. // server.cpp
  3. // ~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2019 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. #include <boost/asio.hpp>
  11. #include <boost/bind.hpp>
  12. #include <boost/lexical_cast.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. namespace s11n_example {
  19. /// Serves stock quote information to any client that connects to it.
  20. class server
  21. {
  22. public:
  23. /// Constructor opens the acceptor and starts waiting for the first incoming
  24. /// connection.
  25. server(boost::asio::io_context& io_context, unsigned short port)
  26. : acceptor_(io_context,
  27. boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port))
  28. {
  29. // Create the data to be sent to each client.
  30. stock s;
  31. s.code = "ABC";
  32. s.name = "A Big Company";
  33. s.open_price = 4.56;
  34. s.high_price = 5.12;
  35. s.low_price = 4.33;
  36. s.last_price = 4.98;
  37. s.buy_price = 4.96;
  38. s.buy_quantity = 1000;
  39. s.sell_price = 4.99;
  40. s.sell_quantity = 2000;
  41. stocks_.push_back(s);
  42. s.code = "DEF";
  43. s.name = "Developer Entertainment Firm";
  44. s.open_price = 20.24;
  45. s.high_price = 22.88;
  46. s.low_price = 19.50;
  47. s.last_price = 19.76;
  48. s.buy_price = 19.72;
  49. s.buy_quantity = 34000;
  50. s.sell_price = 19.85;
  51. s.sell_quantity = 45000;
  52. stocks_.push_back(s);
  53. // Start an accept operation for a new connection.
  54. connection_ptr new_conn(new connection(acceptor_.get_executor()));
  55. acceptor_.async_accept(new_conn->socket(),
  56. boost::bind(&server::handle_accept, this,
  57. boost::asio::placeholders::error, new_conn));
  58. }
  59. /// Handle completion of a accept operation.
  60. void handle_accept(const boost::system::error_code& e, connection_ptr conn)
  61. {
  62. if (!e)
  63. {
  64. // Successfully accepted a new connection. Send the list of stocks to the
  65. // client. The connection::async_write() function will automatically
  66. // serialize the data structure for us.
  67. conn->async_write(stocks_,
  68. boost::bind(&server::handle_write, this,
  69. boost::asio::placeholders::error, conn));
  70. }
  71. // Start an accept operation for a new connection.
  72. connection_ptr new_conn(new connection(acceptor_.get_executor()));
  73. acceptor_.async_accept(new_conn->socket(),
  74. boost::bind(&server::handle_accept, this,
  75. boost::asio::placeholders::error, new_conn));
  76. }
  77. /// Handle completion of a write operation.
  78. void handle_write(const boost::system::error_code& e, connection_ptr conn)
  79. {
  80. // Nothing to do. The socket will be closed automatically when the last
  81. // reference to the connection object goes away.
  82. }
  83. private:
  84. /// The acceptor object used to accept incoming socket connections.
  85. boost::asio::ip::tcp::acceptor acceptor_;
  86. /// The data to be sent to each client.
  87. std::vector<stock> stocks_;
  88. };
  89. } // namespace s11n_example
  90. int main(int argc, char* argv[])
  91. {
  92. try
  93. {
  94. // Check command line arguments.
  95. if (argc != 2)
  96. {
  97. std::cerr << "Usage: server <port>" << std::endl;
  98. return 1;
  99. }
  100. unsigned short port = boost::lexical_cast<unsigned short>(argv[1]);
  101. boost::asio::io_context io_context;
  102. s11n_example::server server(io_context, port);
  103. io_context.run();
  104. }
  105. catch (std::exception& e)
  106. {
  107. std::cerr << e.what() << std::endl;
  108. }
  109. return 0;
  110. }