]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/asio/example/cpp11/spawn/echo_server.cpp
350304e63edc934c046639a0e74131d40bb1c24b
[ceph.git] / ceph / src / boost / libs / asio / example / cpp11 / spawn / echo_server.cpp
1 //
2 // echo_server.cpp
3 // ~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2017 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_context.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_context()),
27 strand_(socket_.get_io_context())
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_context::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_context io_context;
84
85 boost::asio::spawn(io_context,
86 [&](boost::asio::yield_context yield)
87 {
88 tcp::acceptor acceptor(io_context,
89 tcp::endpoint(tcp::v4(), std::atoi(argv[1])));
90
91 for (;;)
92 {
93 boost::system::error_code ec;
94 tcp::socket socket(io_context);
95 acceptor.async_accept(socket, yield[ec]);
96 if (!ec) std::make_shared<session>(std::move(socket))->go();
97 }
98 });
99
100 io_context.run();
101 }
102 catch (std::exception& e)
103 {
104 std::cerr << "Exception: " << e.what() << "\n";
105 }
106
107 return 0;
108 }