]>
Commit | Line | Data |
---|---|---|
b32b8144 FG |
1 | // |
2 | // async_tcp_echo_server.cpp | |
3 | // ~~~~~~~~~~~~~~~~~~~~~~~~~ | |
4 | // | |
f67539c2 | 5 | // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com) |
b32b8144 FG |
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 <cstdlib> | |
12 | #include <iostream> | |
13 | #include <memory> | |
14 | #include <utility> | |
15 | #include <boost/asio.hpp> | |
16 | ||
17 | using boost::asio::ip::tcp; | |
18 | ||
19 | class session | |
20 | : public std::enable_shared_from_this<session> | |
21 | { | |
22 | public: | |
23 | session(tcp::socket socket) | |
24 | : socket_(std::move(socket)) | |
25 | { | |
26 | } | |
27 | ||
28 | void start() | |
29 | { | |
30 | do_read(); | |
31 | } | |
32 | ||
33 | private: | |
34 | void do_read() | |
35 | { | |
36 | auto self(shared_from_this()); | |
37 | socket_.async_read_some(boost::asio::buffer(data_, max_length), | |
38 | [this, self](boost::system::error_code ec, std::size_t length) | |
39 | { | |
40 | if (!ec) | |
41 | { | |
42 | do_write(length); | |
43 | } | |
44 | }); | |
45 | } | |
46 | ||
47 | void do_write(std::size_t length) | |
48 | { | |
49 | auto self(shared_from_this()); | |
50 | boost::asio::async_write(socket_, boost::asio::buffer(data_, length), | |
51 | [this, self](boost::system::error_code ec, std::size_t /*length*/) | |
52 | { | |
53 | if (!ec) | |
54 | { | |
55 | do_read(); | |
56 | } | |
57 | }); | |
58 | } | |
59 | ||
60 | tcp::socket socket_; | |
61 | enum { max_length = 1024 }; | |
62 | char data_[max_length]; | |
63 | }; | |
64 | ||
65 | class server | |
66 | { | |
67 | public: | |
68 | server(boost::asio::io_context& io_context, short port) | |
69 | : acceptor_(io_context, tcp::endpoint(tcp::v4(), port)) | |
70 | { | |
71 | do_accept(); | |
72 | } | |
73 | ||
74 | private: | |
75 | void do_accept() | |
76 | { | |
77 | acceptor_.async_accept( | |
78 | [this](boost::system::error_code ec, tcp::socket socket) | |
79 | { | |
80 | if (!ec) | |
81 | { | |
82 | std::make_shared<session>(std::move(socket))->start(); | |
83 | } | |
84 | ||
85 | do_accept(); | |
86 | }); | |
87 | } | |
88 | ||
89 | tcp::acceptor acceptor_; | |
90 | }; | |
91 | ||
92 | int main(int argc, char* argv[]) | |
93 | { | |
94 | try | |
95 | { | |
96 | if (argc != 2) | |
97 | { | |
98 | std::cerr << "Usage: async_tcp_echo_server <port>\n"; | |
99 | return 1; | |
100 | } | |
101 | ||
102 | boost::asio::io_context io_context; | |
103 | ||
104 | server s(io_context, std::atoi(argv[1])); | |
105 | ||
106 | io_context.run(); | |
107 | } | |
108 | catch (std::exception& e) | |
109 | { | |
110 | std::cerr << "Exception: " << e.what() << "\n"; | |
111 | } | |
112 | ||
113 | return 0; | |
114 | } |