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-​2015·​Christopher·​M.​·​Kohlhoff·​(chris·​at·​kohlhoff·​dot·​com)​5 /​/​·​Copyright·​(c)​·​2003-​2015·​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.​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_service&·io_service)​23 ··​session(tcp:​:​socket·socket)​
22 ····​:​·​socket_(io_service)​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_service&·​io_service,​·​short·​port)​68 ··​server(asio:​:​io_service&·​io_service,​·​short·​port)​
80 ····​:​·​io_service_(io_servic​e)​,​69 ····​:​·acceptor_(io_service,​·tcp:​:​endpoint(tcp:​:​v4()​,​·port)​)​,​
81 ······acceptor_(io_service,​·tcp:​:​endpoint(tcp:​:​v4()​,​·port)​)​70 ······socket_(io_service)​
82 ··​{71 ··​{
83 ····start_accept()​;​72 ····do_accept()​;​
84 ··​}73 ··​}
85 74
86 private:​75 private:​
87 ··​void·start_accept()​76 ··​void·do_accept()​
88 ··{
89 ····session*·new_session·=·new·session(io_service_)​;​
90 ····acceptor_.​async_accept(new_sess​ion-​>socket()​,​
91 ········boost:​:​bind(&server:​:​handle_accept,​·this,​·new_session,​
92 ··········asio:​:​placeholders:​:​error)​)​;​
93 ··}
94
95 ··void·handle_accept(session​*·new_session,​
96 ······const·asio:​:​error_code&·error)​
97 ··​{77 ··​{
98 ····if·(!error)​78 ····acceptor_.​async_accept(socket_,​
99 ····{79 ········[this](std:​:​error_code·ec)​
100 ······new_session-​>start()​;​80 ········{
101 ····}81 ··········if·(!ec)​
102 ····else82 ··········{
103 ····{83 ············std:​:​make_shared<session>(​std:​:​move(socket_)​)​-​>start()​;​
104 ······delete·new_session;​84 ··········}
105 ····}
106 85
107 ····start_accept()​;​86 ··········do_accept()​;​
87 ········​})​;​
108 ··​}88 ··​}
109 89
110 ··​asio:​:​io_service&·​io_service_;​
111 ··​tcp:​:​acceptor·​acceptor_;​90 ··​tcp:​:​acceptor·​acceptor_;​
91 ··​tcp:​:​socket·​socket_;​
112 };​92 };​
113 93
114 int·​main(int·​argc,​·​char*·​argv[])​94 int·​main(int·​argc,​·​char*·​argv[])​
115 {95 {
116 ··​try96 ··​try
117 ··​{97 ··​{
118 ····​if·​(argc·​!=·​2)​98 ····​if·​(argc·​!=·​2)​
119 ····​{99 ····​{
120 ······​std:​:​cerr·​<<·​"Usage:​·​async_tcp_echo_server​·​<port>\n";​100 ······​std:​:​cerr·​<<·​"Usage:​·​async_tcp_echo_server​·​<port>\n";​
121 ······​return·​1;​101 ······​return·​1;​
122 ····​}102 ····​}
123 103
124 ····​asio:​:​io_service·​io_service;​104 ····​asio:​:​io_service·​io_service;​
125 105
126 ····using·namespace·​std;​·/​/​·For·atoi.​106 ····server·s(io_service,​·​std:​:​atoi(argv[1])​)​;​
127 ····server·s(io_service,​·atoi(argv[1])​)​;​
128 107
129 ····​io_service.​run()​;​108 ····​io_service.​run()​;​
130 ··​}109 ··​}
131 ··​catch·​(std:​:​exception&·​e)​110 ··​catch·​(std:​:​exception&·​e)​
132 ··​{111 ··​{
133 ····​std:​:​cerr·​<<·​"Exception:​·​"·​<<·​e.​what()​·​<<·​"\n";​112 ····​std:​:​cerr·​<<·​"Exception:​·​"·​<<·​e.​what()​·​<<·​"\n";​
134 ··​}113 ··​}
135 114
136 ··​return·​0;​115 ··​return·​0;​
137 }116 }