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-​2023·​Christopher·​M.​·​Kohlhoff·​(chris·​at·​kohlhoff·​dot·​com)​5 /​/​·​Copyright·​(c)​·​2003-​2023·​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()​51 ·​·​void·​start()​
52 ·​·​{52 ·​·​{
53 ·​·​·​·​return·​socket_;​53 ·​·​·​·​do_write()​;​
54 ·​·​}54 ·​·​}
55 55
56 ·​·​void·​start()​56 private:​
57 ·​·​void·​do_write()​
57 ·​·​{58 ·​·​{
58 ·​·​·​·​using·​namespace·​std;​·​/​/​·​For·​time_t,​·​time·​and·​ctime.​59 ·​·​·​·​std:​:​time_t·​now·​=·​std:​:​time(0)​;​
59 ·​·​·​·​time_t·​now·​=·​time(0)​;​60 ·​·​·​·​shared_const_buffer·​buffer(std:​:​ctime(&now)​)​;​
60 ·​·​·​·​shared_const_buffer·​buffer(ctime(&now)​)​;​61
62 ·​·​·​·​auto·​self(shared_from_this​()​)​;​
61 ·​·​·​·​asio:​:​async_write(socket_,​·​buffer,​63 ·​·​·​·​asio:​:​async_write(socket_,​·​buffer,​
62 ·​·​·​·​·​·​·​·​boost:​:​bind(&session:​:​handle_write,​·​shared_from_this()​)​)​;​64 ·​·​·​·​·​·​·​·​[self](std:​:​error_code·​/​*ec*/​,​·​std:​:​size_t·​/​*length*/​)​
65 ·​·​·​·​·​·​·​·​{
66 ·​·​·​·​·​·​·​·​})​;​
63 ·​·​}67 ·​·​}
64 68
65 ·​·​void·​handle_write()​
66 ·​·​{
67 ·​·​}
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 }