• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // server.cpp
3 // ~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2021 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 <ctime>
12 #include <iostream>
13 #include <string>
14 #include <boost/bind/bind.hpp>
15 #include <boost/shared_ptr.hpp>
16 #include <boost/enable_shared_from_this.hpp>
17 #include <boost/asio.hpp>
18 
19 using boost::asio::ip::tcp;
20 
make_daytime_string()21 std::string make_daytime_string()
22 {
23   using namespace std; // For time_t, time and ctime;
24   time_t now = time(0);
25   return ctime(&now);
26 }
27 
28 class tcp_connection
29   : public boost::enable_shared_from_this<tcp_connection>
30 {
31 public:
32   typedef boost::shared_ptr<tcp_connection> pointer;
33 
create(boost::asio::io_context & io_context)34   static pointer create(boost::asio::io_context& io_context)
35   {
36     return pointer(new tcp_connection(io_context));
37   }
38 
socket()39   tcp::socket& socket()
40   {
41     return socket_;
42   }
43 
start()44   void start()
45   {
46     message_ = make_daytime_string();
47 
48     boost::asio::async_write(socket_, boost::asio::buffer(message_),
49         boost::bind(&tcp_connection::handle_write, shared_from_this(),
50           boost::asio::placeholders::error,
51           boost::asio::placeholders::bytes_transferred));
52   }
53 
54 private:
tcp_connection(boost::asio::io_context & io_context)55   tcp_connection(boost::asio::io_context& io_context)
56     : socket_(io_context)
57   {
58   }
59 
handle_write(const boost::system::error_code &,size_t)60   void handle_write(const boost::system::error_code& /*error*/,
61       size_t /*bytes_transferred*/)
62   {
63   }
64 
65   tcp::socket socket_;
66   std::string message_;
67 };
68 
69 class tcp_server
70 {
71 public:
tcp_server(boost::asio::io_context & io_context)72   tcp_server(boost::asio::io_context& io_context)
73     : io_context_(io_context),
74       acceptor_(io_context, tcp::endpoint(tcp::v4(), 13))
75   {
76     start_accept();
77   }
78 
79 private:
start_accept()80   void start_accept()
81   {
82     tcp_connection::pointer new_connection =
83       tcp_connection::create(io_context_);
84 
85     acceptor_.async_accept(new_connection->socket(),
86         boost::bind(&tcp_server::handle_accept, this, new_connection,
87           boost::asio::placeholders::error));
88   }
89 
handle_accept(tcp_connection::pointer new_connection,const boost::system::error_code & error)90   void handle_accept(tcp_connection::pointer new_connection,
91       const boost::system::error_code& error)
92   {
93     if (!error)
94     {
95       new_connection->start();
96     }
97 
98     start_accept();
99   }
100 
101   boost::asio::io_context& io_context_;
102   tcp::acceptor acceptor_;
103 };
104 
main()105 int main()
106 {
107   try
108   {
109     boost::asio::io_context io_context;
110     tcp_server server(io_context);
111     io_context.run();
112   }
113   catch (std::exception& e)
114   {
115     std::cerr << e.what() << std::endl;
116   }
117 
118   return 0;
119 }
120