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-​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·​<asio.​hpp>11 #include·​<asio.​hpp>
12 #include·​<boost/​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>
17 16
18 using·​asio:​:​ip:​:​tcp;​17 using·​asio:​:​ip:​:​tcp;​
19 18
20 /​/​·​A·​reference-​counted·​non-​modifiable·​buffer·​class.​19 /​/​·​A·​reference-​counted·​non-​modifiable·​buffer·​class.​
21 class·​shared_const_buffer20 class·​shared_const_buffer
22 {21 {
23 public:​22 public:​
24 ··​/​/​·​Construct·​from·​a·​std:​:​string.​23 ··​/​/​·​Construct·​from·​a·​std:​:​string.​
25 ··​explicit·​shared_const_buffer(c​onst·​std:​:​string&·​data)​24 ··​explicit·​shared_const_buffer(c​onst·​std:​:​string&·​data)​
26 ····​:​·​data_(new·​std:​:​vector<char>(data.​begin()​,​·​data.​end()​)​)​,​25 ····​:​·​data_(new·​std:​:​vector<char>(data.​begin()​,​·​data.​end()​)​)​,​
27 ······​buffer_(asio:​:​buffer(*data_)​)​26 ······​buffer_(asio:​:​buffer(*data_)​)​
28 ··​{27 ··​{
29 ··​}28 ··​}
30 29
31 ··​/​/​·​Implement·​the·​ConstBufferSequence·​requirements.​30 ··​/​/​·​Implement·​the·​ConstBufferSequence·​requirements.​
32 ··​typedef·​asio:​:​const_buffer·​value_type;​31 ··​typedef·​asio:​:​const_buffer·​value_type;​
33 ··​typedef·​const·​asio:​:​const_buffer*·​const_iterator;​32 ··​typedef·​const·​asio:​:​const_buffer*·​const_iterator;​
34 ··​const·​asio:​:​const_buffer*·​begin()​·​const·​{·​return·​&buffer_;​·​}33 ··​const·​asio:​:​const_buffer*·​begin()​·​const·​{·​return·​&buffer_;​·​}
35 ··​const·​asio:​:​const_buffer*·​end()​·​const·​{·​return·​&buffer_·​+·​1;​·​}34 ··​const·​asio:​:​const_buffer*·​end()​·​const·​{·​return·​&buffer_·​+·​1;​·​}
36 35
37 private:​36 private:​
38 ··boost:​:​shared_ptr<std:​:​vector<char>·​>·​data_;​37 ··​std:​:​shared_ptr<std:​:​vector<char>·​>·​data_;​
39 ··​asio:​:​const_buffer·​buffer_;​38 ··​asio:​:​const_buffer·​buffer_;​
40 };​39 };​
41 40
42 class·​session41 class·​session
43 ··​:​·​public·boost:​:​enable_shared_from_th​is<session>42 ··​:​·​public·​std:​:​enable_shared_from_th​is<session>
44 {43 {
45 public:​44 public:​
46 ··​session(asio:​:​io_service&·io_service)​45 ··​session(tcp:​:​socket·socket)​
47 ····​:​·​socket_(io_service)​46 ····​:​·​socket_(std:​:​move(socket)​)​
48 ··​{47 ··​{
49 ··​}48 ··​}
50 49
51 ··​tcp:​:​socket&·​socket()​
52 ··​{
53 ····​return·​socket_;​
54 ··​}
55
56 ··​void·​start()​50 ··​void·​start()​
57 ··​{51 ··​{
58 ····using·namespace·std;​·/​/​·For·time_t,​·time·and·ctime.​52 ····​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 ··​}53 ··​}
64 54
65 ··void·handle_write()​55 private:​
56 ··​void·​do_write()​
66 ··​{57 ··​{
58 ····​std:​:​time_t·​now·​=·​std:​:​time(0)​;​
59 ····​shared_const_buffer·​buffer(std:​:​ctime(&now)​)​;​
60
61 ····​auto·​self(shared_from_this​()​)​;​
62 ····​asio:​:​async_write(socket_,​·​buffer,​
63 ········​[this,​·​self](std:​:​error_code·​/​*ec*/​,​·​std:​:​size_t·​/​*length*/​)​
64 ········​{
65 ········​})​;​
67 ··​}66 ··​}
68 67
69 private:​
70 ··​/​/​·​The·​socket·​used·​to·​communicate·​with·​the·​client.​68 ··​/​/​·​The·​socket·​used·​to·​communicate·​with·​the·​client.​
71 ··​tcp:​:​socket·​socket_;​69 ··​tcp:​:​socket·​socket_;​
72 };​70 };​
73 71
74 typedef·​boost:​:​shared_ptr<session>·​session_ptr;​
75
76 class·​server72 class·​server
77 {73 {
78 public:​74 public:​
79 ··​server(asio:​:​io_service&·​io_service,​·​short·​port)​75 ··​server(asio:​:​io_service&·​io_service,​·​short·​port)​
80 ····​:​·​io_service_(io_servic​e)​,​76 ····​:​·acceptor_(io_service,​·tcp:​:​endpoint(tcp:​:​v4()​,​·port)​)​,​
81 ······acceptor_(io_service,​·tcp:​:​endpoint(tcp:​:​v4()​,​·port)​)​77 ······socket_(io_service)​
82 ··​{78 ··​{
83 ····session_ptr·new_session(new·session(io_service_)​)​;​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(socket_,​
93 ····{86 ········[this](std:​:​error_code·ec)​
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_service_)​)​;​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_service&·​io_service_;​
105 ··​tcp:​:​acceptor·​acceptor_;​97 ··​tcp:​:​acceptor·​acceptor_;​
98 ··​tcp:​:​socket·​socket_;​
106 };​99 };​
107 100
108 int·​main(int·​argc,​·​char*·​argv[])​101 int·​main(int·​argc,​·​char*·​argv[])​
109 {102 {
110 ··​try103 ··​try
111 ··​{104 ··​{
112 ····​if·​(argc·​!=·​2)​105 ····​if·​(argc·​!=·​2)​
113 ····​{106 ····​{
114 ······​std:​:​cerr·​<<·​"Usage:​·​reference_counted·​<port>\n";​107 ······​std:​:​cerr·​<<·​"Usage:​·​reference_counted·​<port>\n";​
115 ······​return·​1;​108 ······​return·​1;​
116 ····​}109 ····​}
117 110
118 ····​asio:​:​io_service·​io_service;​111 ····​asio:​:​io_service·​io_service;​
119 112
120 ····using·namespace·​std;​·/​/​·For·atoi.​113 ····server·s(io_service,​·​std:​:​atoi(argv[1])​)​;​
121 ····server·s(io_service,​·atoi(argv[1])​)​;​
122 114
123 ····​io_service.​run()​;​115 ····​io_service.​run()​;​
124 ··​}116 ··​}
125 ··​catch·​(std:​:​exception&·​e)​117 ··​catch·​(std:​:​exception&·​e)​
126 ··​{118 ··​{
127 ····​std:​:​cerr·​<<·​"Exception:​·​"·​<<·​e.​what()​·​<<·​"\n";​119 ····​std:​:​cerr·​<<·​"Exception:​·​"·​<<·​e.​what()​·​<<·​"\n";​
128 ··​}120 ··​}
129 121
130 ··​return·​0;​122 ··​return·​0;​
131 }123 }