Imported Upstream version 1.57.0
[platform/upstream/boost.git] / doc / html / boost_asio / example / cpp11 / spawn / echo_server.cpp
1 //
2 // echo_server.cpp
3 // ~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2014 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/io_service.hpp>
12 #include <boost/asio/ip/tcp.hpp>
13 #include <boost/asio/spawn.hpp>
14 #include <boost/asio/steady_timer.hpp>
15 #include <boost/asio/write.hpp>
16 #include <iostream>
17 #include <memory>
18
19 using boost::asio::ip::tcp;
20
21 class session : public std::enable_shared_from_this<session>
22 {
23 public:
24   explicit session(tcp::socket socket)
25     : socket_(std::move(socket)),
26       timer_(socket_.get_io_service()),
27       strand_(socket_.get_io_service())
28   {
29   }
30
31   void go()
32   {
33     auto self(shared_from_this());
34     boost::asio::spawn(strand_,
35         [this, self](boost::asio::yield_context yield)
36         {
37           try
38           {
39             char data[128];
40             for (;;)
41             {
42               timer_.expires_from_now(std::chrono::seconds(10));
43               std::size_t n = socket_.async_read_some(boost::asio::buffer(data), yield);
44               boost::asio::async_write(socket_, boost::asio::buffer(data, n), yield);
45             }
46           }
47           catch (std::exception& e)
48           {
49             socket_.close();
50             timer_.cancel();
51           }
52         });
53
54     boost::asio::spawn(strand_,
55         [this, self](boost::asio::yield_context yield)
56         {
57           while (socket_.is_open())
58           {
59             boost::system::error_code ignored_ec;
60             timer_.async_wait(yield[ignored_ec]);
61             if (timer_.expires_from_now() <= std::chrono::seconds(0))
62               socket_.close();
63           }
64         });
65   }
66
67 private:
68   tcp::socket socket_;
69   boost::asio::steady_timer timer_;
70   boost::asio::io_service::strand strand_;
71 };
72
73 int main(int argc, char* argv[])
74 {
75   try
76   {
77     if (argc != 2)
78     {
79       std::cerr << "Usage: echo_server <port>\n";
80       return 1;
81     }
82
83     boost::asio::io_service io_service;
84
85     boost::asio::spawn(io_service,
86         [&](boost::asio::yield_context yield)
87         {
88           tcp::acceptor acceptor(io_service,
89             tcp::endpoint(tcp::v4(), std::atoi(argv[1])));
90
91           for (;;)
92           {
93             boost::system::error_code ec;
94             tcp::socket socket(io_service);
95             acceptor.async_accept(socket, yield[ec]);
96             if (!ec) std::make_shared<session>(std::move(socket))->go();
97           }
98         });
99
100     io_service.run();
101   }
102   catch (std::exception& e)
103   {
104     std::cerr << "Exception: " << e.what() << "\n";
105   }
106
107   return 0;
108 }