src/​examples/​cpp03/​echo/​async_tcp_echo_server​.​cppsrc/​examples/​cpp11/​echo/​async_tcp_echo_server​.​cpp
1 /​/​1 /​/​
2 /​/​·​async_tcp_echo_server​.​cpp2 /​/​·​async_tcp_echo_server​.​cpp
3 /​/​·​~~~~~~~~~~~~~~~~~~~~~​~~~~3 /​/​·​~~~~~~~~~~~~~~~~~~~~~​~~~~
4 /​/​4 /​/​
5 /​/​·​Copyright·​(c)​·​2003-​2022·​Christopher·​M.​·​Kohlhoff·​(chris·​at·​kohlhoff·​dot·​com)​5 /​/​·​Copyright·​(c)​·​2003-​2022·​Christopher·​M.​·​Kohlhoff·​(chris·​at·​kohlhoff·​dot·​com)​
6 /​/​6 /​/​
7 /​/​·​Distributed·​under·​the·​Boost·​Software·​License,​·​Version·​1.​0.​·​(See·​accompanying7 /​/​·​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)​8 /​/​·​file·​LICENSE_1_0.​txt·​or·​copy·​at·​http:​/​/​www.​boost.​org/​LICENSE_1_0.​txt)​
9 /​/​9 /​/​
10 10
11 #include·​<cstdlib>11 #include·​<cstdlib>
12 #include·​<iostream>12 #include·​<iostream>
13 #include·​<boost/​bind/​bind.​hpp>13 #include·​<memory>
14 #include·​<utility>
14 #include·​"asio.​hpp"15 #include·​"asio.​hpp"
15 16
16 using·​asio:​:​ip:​:​tcp;​17 using·​asio:​:​ip:​:​tcp;​
17 18
18 class·​session19 class·​session
20 ··​:​·​public·​std:​:​enable_shared_from_th​is<session>
19 {21 {
20 public:​22 public:​
21 ··​session(asio:​:​io_context&·io_context)​23 ··​session(tcp:​:​socket·socket)​
22 ····​:​·​socket_(io_context)​24 ····​:​·​socket_(std:​:​move(socket)​)​
23 ··​{25 ··​{
24 ··​}26 ··​}
25 27
26 ··​tcp:​:​socket&·​socket()​
27 ··​{
28 ····​return·​socket_;​
29 ··​}
30
31 ··​void·​start()​28 ··​void·​start()​
32 ··​{29 ··​{
33 ····socket_.​async_read_some(asio:​:​buffer(data_,​·max_length)​,​30 ····do_read()​;​
34 ········boost:​:​bind(&session:​:​handle_read,​·this,​
35 ··········asio:​:​placeholders:​:​error,​
36 ··········asio:​:​placeholders:​:​bytes_transferred)​)​;​
37 ··​}31 ··​}
38 32
39 private:​33 private:​
40 ··​void·handle_read(const·asio:​:​error_code&·error,​34 ··​void·​do_read()​
41 ······size_t·bytes_transferred)​
42 ··{
43 ····if·(!error)​
44 ····{
45 ······asio:​:​async_write(socket_,​
46 ··········asio:​:​buffer(data_,​·bytes_transferred)​,​
47 ··········boost:​:​bind(&session:​:​handle_write,​·this,​
48 ············asio:​:​placeholders:​:​error)​)​;​
49 ····}
50 ····else
51 ····{
52 ······delete·this;​
53 ····}
54 ··}
55
56 ··void·handle_write(const·asio:​:​error_code&·error)​
57 ··​{35 ··​{
58 ····if·​(!error)​36 ····auto·self(shared_from_this​()​)​;​
59 ····{37 ····socket_.​async_read_some(asio:​:​buffer(data_,​·max_length)​,​
60 ······socket_.​async_read_some(asio:​:​buffer(data_,​·max_length)​,​38 ········[this,​·self](std:​:​error_code·ec,​·std:​:​size_t·length)​
61 ··········boost:​:​bind(&session:​:​handle_read,​·this,​39 ········{
62 ············asio:​:​placeholders:​:​error,​40 ··········​if·(!ec)​
63 ············asio:​:​placeholders:​:​bytes_transferred)​)​;​41 ··········{
64 ····}42 ············do_write(length)​;​
65 ····else43 ··········}
66 ····{44 ········})​;​
67 ······delete·this;​45 ··}
68 ····}46
47 ··​void·​do_write(std:​:​size_t·​length)​
48 ··​{
49 ····​auto·​self(shared_from_this​()​)​;​
50 ····​asio:​:​async_write(socket_,​·​asio:​:​buffer(data_,​·​length)​,​
51 ········​[this,​·​self](std:​:​error_code·​ec,​·​std:​:​size_t·​/​*length*/​)​
52 ········​{
53 ··········​if·​(!ec)​
54 ··········​{
55 ············​do_read()​;​
56 ··········​}
57 ········​})​;​
69 ··​}58 ··​}
70 59
71 ··​tcp:​:​socket·​socket_;​60 ··​tcp:​:​socket·​socket_;​
72 ··​enum·​{·​max_length·​=·​1024·​};​61 ··​enum·​{·​max_length·​=·​1024·​};​
73 ··​char·​data_[max_length];​62 ··​char·​data_[max_length];​
74 };​63 };​
75 64
76 class·​server65 class·​server
77 {66 {
78 public:​67 public:​
79 ··​server(asio:​:​io_context&·​io_context,​·​short·​port)​68 ··​server(asio:​:​io_context&·​io_context,​·​short·​port)​
80 ····​:​·​io_context_(io_contex​t)​,​69 ····​:​·acceptor_(io_context,​·tcp:​:​endpoint(tcp:​:​v4()​,​·port)​)​
81 ······acceptor_(io_context,​·tcp:​:​endpoint(tcp:​:​v4()​,​·port)​)​
82 ··​{70 ··​{
83 ····start_accept()​;​71 ····do_accept()​;​
84 ··​}72 ··​}
85 73
86 private:​74 private:​
87 ··​void·start_accept()​75 ··​void·do_accept()​
88 ··​{76 ··​{
89 ····session*·new_session·=·new·session(io_context_)​;​77 ····acceptor_.​async_accept(
90 ····acceptor_.​async_accept(new_sess​ion-​>socket()​,​78 ········[this](std:​:​error_code·ec,​·tcp:​:​socket·socket)​
91 ········boost:​:​bind(&server:​:​handle_accept,​·this,​·new_session,​79 ········{
92 ··········asio:​:​placeholders:​:​error)​)​;​80 ··········​if·(!ec)​
93 ··}81 ··········{
94 82 ············std:​:​make_shared<session>(​std:​:​move(socket)​)​-​>start()​;​
95 ··void·handle_accept(session​*·new_session,​83 ··········}
96 ······const·asio:​:​error_code&·error)​
97 ··{
98 ····if·(!error)​
99 ····{
100 ······new_session-​>start()​;​
101 ····}
102 ····else
103 ····{
104 ······delete·new_session;​
105 ····}
106 84
107 ····start_accept()​;​85 ··········do_accept()​;​
86 ········​})​;​
108 ··​}87 ··​}
109 88
110 ··​asio:​:​io_context&·​io_context_;​
111 ··​tcp:​:​acceptor·​acceptor_;​89 ··​tcp:​:​acceptor·​acceptor_;​
112 };​90 };​
113 91
114 int·​main(int·​argc,​·​char*·​argv[])​92 int·​main(int·​argc,​·​char*·​argv[])​
115 {93 {
116 ··​try94 ··​try
117 ··​{95 ··​{
118 ····​if·​(argc·​!=·​2)​96 ····​if·​(argc·​!=·​2)​
119 ····​{97 ····​{
120 ······​std:​:​cerr·​<<·​"Usage:​·​async_tcp_echo_server​·​<port>\n";​98 ······​std:​:​cerr·​<<·​"Usage:​·​async_tcp_echo_server​·​<port>\n";​
121 ······​return·​1;​99 ······​return·​1;​
122 ····​}100 ····​}
123 101
124 ····​asio:​:​io_context·​io_context;​102 ····​asio:​:​io_context·​io_context;​
125 103
126 ····using·namespace·​std;​·/​/​·For·atoi.​104 ····server·s(io_context,​·​std:​:​atoi(argv[1])​)​;​
127 ····server·s(io_context,​·atoi(argv[1])​)​;​
128 105
129 ····​io_context.​run()​;​106 ····​io_context.​run()​;​
130 ··​}107 ··​}
131 ··​catch·​(std:​:​exception&·​e)​108 ··​catch·​(std:​:​exception&·​e)​
132 ··​{109 ··​{
133 ····​std:​:​cerr·​<<·​"Exception:​·​"·​<<·​e.​what()​·​<<·​"\n";​110 ····​std:​:​cerr·​<<·​"Exception:​·​"·​<<·​e.​what()​·​<<·​"\n";​
134 ··​}111 ··​}
135 112
136 ··​return·​0;​113 ··​return·​0;​
137 }114 }