src/​examples/​cpp03/​buffers/​reference_counted.​cppsrc/​examples/​cpp11/​buffers/​reference_counted.​cpp
1 /​/​1 /​/​
2 /​/​·​reference_counted.​cpp2 /​/​·​reference_counted.​cpp
3 /​/​·​~~~~~~~~~~~~~~~~~~~~~​3 /​/​·​~~~~~~~~~~~~~~~~~~~~~​
4 /​/​4 /​/​
5 /​/​·​Copyright·​(c)​·​2003-​2020·​Christopher·​M.​·​Kohlhoff·​(chris·​at·​kohlhoff·​dot·​com)​5 /​/​·​Copyright·​(c)​·​2003-​2020·​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·​<asio.​hpp>11 #include·​<asio.​hpp>
12 #include·​<boost/​bind/​bind.​hpp>
13 #include·​<boost/​enable_shared_from_th​is.​hpp>
14 #include·​<boost/​shared_ptr.​hpp>
15 #include·​<iostream>12 #include·​<iostream>
13 #include·​<memory>
14 #include·​<utility>
16 #include·​<vector>15 #include·​<vector>
16 #include·​<ctime>
17 17
18 using·​asio:​:​ip:​:​tcp;​18 using·​asio:​:​ip:​:​tcp;​
19 19
20 /​/​·​A·​reference-​counted·​non-​modifiable·​buffer·​class.​20 /​/​·​A·​reference-​counted·​non-​modifiable·​buffer·​class.​
21 class·​shared_const_buffer21 class·​shared_const_buffer
22 {22 {
23 public:​23 public:​
24 ··​/​/​·​Construct·​from·​a·​std:​:​string.​24 ··​/​/​·​Construct·​from·​a·​std:​:​string.​
25 ··​explicit·​shared_const_buffer(c​onst·​std:​:​string&·​data)​25 ··​explicit·​shared_const_buffer(c​onst·​std:​:​string&·​data)​
26 ····​:​·​data_(new·​std:​:​vector<char>(data.​begin()​,​·​data.​end()​)​)​,​26 ····​:​·​data_(new·​std:​:​vector<char>(data.​begin()​,​·​data.​end()​)​)​,​
27 ······​buffer_(asio:​:​buffer(*data_)​)​27 ······​buffer_(asio:​:​buffer(*data_)​)​
28 ··​{28 ··​{
29 ··​}29 ··​}
30 30
31 ··​/​/​·​Implement·​the·​ConstBufferSequence·​requirements.​31 ··​/​/​·​Implement·​the·​ConstBufferSequence·​requirements.​
32 ··​typedef·​asio:​:​const_buffer·​value_type;​32 ··​typedef·​asio:​:​const_buffer·​value_type;​
33 ··​typedef·​const·​asio:​:​const_buffer*·​const_iterator;​33 ··​typedef·​const·​asio:​:​const_buffer*·​const_iterator;​
34 ··​const·​asio:​:​const_buffer*·​begin()​·​const·​{·​return·​&buffer_;​·​}34 ··​const·​asio:​:​const_buffer*·​begin()​·​const·​{·​return·​&buffer_;​·​}
35 ··​const·​asio:​:​const_buffer*·​end()​·​const·​{·​return·​&buffer_·​+·​1;​·​}35 ··​const·​asio:​:​const_buffer*·​end()​·​const·​{·​return·​&buffer_·​+·​1;​·​}
36 36
37 private:​37 private:​
38 ··boost:​:​shared_ptr<std:​:​vector<char>·​>·​data_;​38 ··​std:​:​shared_ptr<std:​:​vector<char>·​>·​data_;​
39 ··​asio:​:​const_buffer·​buffer_;​39 ··​asio:​:​const_buffer·​buffer_;​
40 };​40 };​
41 41
42 class·​session42 class·​session
43 ··​:​·​public·boost:​:​enable_shared_from_th​is<session>43 ··​:​·​public·​std:​:​enable_shared_from_th​is<session>
44 {44 {
45 public:​45 public:​
46 ··​session(asio:​:​io_context&·io_context)​46 ··​session(tcp:​:​socket·socket)​
47 ····​:​·​socket_(io_context)​47 ····​:​·​socket_(std:​:​move(socket)​)​
48 ··​{48 ··​{
49 ··​}49 ··​}
50 50
51 ··​tcp:​:​socket&·​socket()​
52 ··​{
53 ····​return·​socket_;​
54 ··​}
55
56 ··​void·​start()​51 ··​void·​start()​
57 ··​{52 ··​{
58 ····using·namespace·std;​·/​/​·For·time_t,​·time·and·ctime.​53 ····​do_write()​;​
59 ····time_t·now·=·time(0)​;​
60 ····shared_const_buffer·buffer(ctime(&now)​)​;​
61 ····asio:​:​async_write(socket_,​·buffer,​
62 ········boost:​:​bind(&session:​:​handle_write,​·shared_from_this()​)​)​;​
63 ··​}54 ··​}
64 55
65 ··void·handle_write()​56 private:​
57 ··​void·​do_write()​
66 ··​{58 ··​{
59 ····​std:​:​time_t·​now·​=·​std:​:​time(0)​;​
60 ····​shared_const_buffer·​buffer(std:​:​ctime(&now)​)​;​
61
62 ····​auto·​self(shared_from_this​()​)​;​
63 ····​asio:​:​async_write(socket_,​·​buffer,​
64 ········​[self](std:​:​error_code·​/​*ec*/​,​·​std:​:​size_t·​/​*length*/​)​
65 ········​{
66 ········​})​;​
67 ··​}67 ··​}
68 68
69 private:​
70 ··​/​/​·​The·​socket·​used·​to·​communicate·​with·​the·​client.​69 ··​/​/​·​The·​socket·​used·​to·​communicate·​with·​the·​client.​
71 ··​tcp:​:​socket·​socket_;​70 ··​tcp:​:​socket·​socket_;​
72 };​71 };​
73 72
74 typedef·​boost:​:​shared_ptr<session>·​session_ptr;​
75
76 class·​server73 class·​server
77 {74 {
78 public:​75 public:​
79 ··​server(asio:​:​io_context&·​io_context,​·​short·​port)​76 ··​server(asio:​:​io_context&·​io_context,​·​short·​port)​
80 ····​:​·​io_context_(io_contex​t)​,​77 ····​:​·acceptor_(io_context,​·tcp:​:​endpoint(tcp:​:​v4()​,​·port)​)​
81 ······acceptor_(io_context,​·tcp:​:​endpoint(tcp:​:​v4()​,​·port)​)​
82 ··​{78 ··​{
83 ····session_ptr·new_session(new·session(io_context_)​)​;​79 ····do_accept()​;​
84 ····acceptor_.​async_accept(new_sess​ion-​>socket()​,​
85 ········boost:​:​bind(&server:​:​handle_accept,​·this,​·new_session,​
86 ··········asio:​:​placeholders:​:​error)​)​;​
87 ··​}80 ··​}
88 81
89 ··void·handle_accept(session​_ptr·new_session,​82 private:​
90 ······const·asio:​:​error_code&·error)​83 ··void·do_accept()​
91 ··​{84 ··​{
92 ····if·(!error)​85 ····acceptor_.​async_accept(
93 ····{86 ········[this](std:​:​error_code·ec,​·tcp:​:​socket·socket)​
94 ······new_session-​>start()​;​87 ········{
95 ····}88 ··········if·(!ec)​
89 ··········​{
90 ············​std:​:​make_shared<session>(​std:​:​move(socket)​)​-​>start()​;​
91 ··········​}
96 92
97 ····new_session.​reset(new·session(io_context_)​)​;​93 ··········do_accept()​;​
98 ····acceptor_.​async_accept(new_sess​ion-​>socket()​,​94 ········})​;​
99 ········boost:​:​bind(&server:​:​handle_accept,​·this,​·new_session,​
100 ··········asio:​:​placeholders:​:​error)​)​;​
101 ··​}95 ··​}
102 96
103 private:​
104 ··​asio:​:​io_context&·​io_context_;​
105 ··​tcp:​:​acceptor·​acceptor_;​97 ··​tcp:​:​acceptor·​acceptor_;​
106 };​98 };​
107 99
108 int·​main(int·​argc,​·​char*·​argv[])​100 int·​main(int·​argc,​·​char*·​argv[])​
109 {101 {
110 ··​try102 ··​try
111 ··​{103 ··​{
112 ····​if·​(argc·​!=·​2)​104 ····​if·​(argc·​!=·​2)​
113 ····​{105 ····​{
114 ······​std:​:​cerr·​<<·​"Usage:​·​reference_counted·​<port>\n";​106 ······​std:​:​cerr·​<<·​"Usage:​·​reference_counted·​<port>\n";​
115 ······​return·​1;​107 ······​return·​1;​
116 ····​}108 ····​}
117 109
118 ····​asio:​:​io_context·​io_context;​110 ····​asio:​:​io_context·​io_context;​
119 111
120 ····using·namespace·​std;​·/​/​·For·atoi.​112 ····server·s(io_context,​·​std:​:​atoi(argv[1])​)​;​
121 ····server·s(io_context,​·atoi(argv[1])​)​;​
122 113
123 ····​io_context.​run()​;​114 ····​io_context.​run()​;​
124 ··​}115 ··​}
125 ··​catch·​(std:​:​exception&·​e)​116 ··​catch·​(std:​:​exception&·​e)​
126 ··​{117 ··​{
127 ····​std:​:​cerr·​<<·​"Exception:​·​"·​<<·​e.​what()​·​<<·​"\n";​118 ····​std:​:​cerr·​<<·​"Exception:​·​"·​<<·​e.​what()​·​<<·​"\n";​
128 ··​}119 ··​}
129 120
130 ··​return·​0;​121 ··​return·​0;​
131 }122 }