src/​examples/​cpp03/​chat/​chat_server.​cppsrc/​examples/​cpp11/​chat/​chat_server.​cpp
⋮⋮
1 /​/​1 /​/​
2 /​/​·​chat_server.​cpp2 /​/​·​chat_server.​cpp
3 /​/​·​~~~~~~~~~~~~~~~3 /​/​·​~~~~~~~~~~~~~~~
4 /​/​4 /​/​
5 /​/​·​Copyright·​(c)​·​2003-​2018·​Christopher·​M.​·​Kohlhoff·​(chris·​at·​kohlhoff·​dot·​com)​5 /​/​·​Copyright·​(c)​·​2003-​2018·​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·​<algorithm>
12 #include·​<cstdlib>11 #include·​<cstdlib>
13 #include·​<deque>12 #include·​<deque>
14 #include·​<iostream>13 #include·​<iostream>
15 #include·​<list>14 #include·​<list>
15 #include·​<memory>
16 #include·​<set>16 #include·​<set>
17 #include·​<boost/​bind.​hpp>17 #include·​<utility>
18 #include·​<boost/​shared_ptr.​hpp>
19 #include·​<boost/​enable_shared_from_th​is.​hpp>
20 #include·​"asio.​hpp"18 #include·​"asio.​hpp"
21 #include·​"chat_message.​hpp"19 #include·​"chat_message.​hpp"
22 20
23 using·​asio:​:​ip:​:​tcp;​21 using·​asio:​:​ip:​:​tcp;​
24 22
25 /​/​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​23 /​/​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​
26 24
27 typedef·​std:​:​deque<chat_message>·​chat_message_queue;​25 typedef·​std:​:​deque<chat_message>·​chat_message_queue;​
28 26
29 /​/​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​27 /​/​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​
30 28
31 class·​chat_participant29 class·​chat_participant
32 {30 {
33 public:​31 public:​
34 ·​·​virtual·​~chat_participant()​·​{}32 ·​·​virtual·​~chat_participant()​·​{}
35 ·​·​virtual·​void·​deliver(const·​chat_message&·​msg)​·​=·​0;​33 ·​·​virtual·​void·​deliver(const·​chat_message&·​msg)​·​=·​0;​
36 };​34 };​
37 35
38 typedef·​boost:​:​shared_ptr<chat_parti​cipant>·​chat_participant_ptr;​36 typedef·​std:​:​shared_ptr<chat_parti​cipant>·​chat_participant_ptr;​
39 37
40 /​/​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​38 /​/​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​
41 39
42 class·​chat_room40 class·​chat_room
43 {41 {
44 public:​42 public:​
45 ·​·​void·​join(chat_participant​_ptr·​participant)​43 ·​·​void·​join(chat_participant​_ptr·​participant)​
46 ·​·​{44 ·​·​{
47 ·​·​·​·​participants_.​insert(participant)​;​45 ·​·​·​·​participants_.​insert(participant)​;​
48 ·​·​·​·​std:​:​for_each(recent_msgs_​.​begin()​,​·​recent_msgs_.​end()​,​46 ·​·​·​·​for·​(auto·​msg:​·​recent_msgs_)​
49 ·​·​·​·​·​·​·​·​boost:​:​bind(&chat_participan​t:​:​deliver,​·​participant,​·​_1)​)​;​47 ·​·​·​·​·​·​participant-​>deliver(msg)​;​
50 ·​·​}48 ·​·​}
51 49
52 ·​·​void·​leave(chat_participan​t_ptr·​participant)​50 ·​·​void·​leave(chat_participan​t_ptr·​participant)​
53 ·​·​{51 ·​·​{
54 ·​·​·​·​participants_.​erase(participant)​;​52 ·​·​·​·​participants_.​erase(participant)​;​
55 ·​·​}53 ·​·​}
56 54
57 ·​·​void·​deliver(const·​chat_message&·​msg)​55 ·​·​void·​deliver(const·​chat_message&·​msg)​
58 ·​·​{56 ·​·​{
59 ·​·​·​·​recent_msgs_.​push_back(msg)​;​57 ·​·​·​·​recent_msgs_.​push_back(msg)​;​
60 ·​·​·​·​while·​(recent_msgs_.​size()​·​>·​max_recent_msgs)​58 ·​·​·​·​while·​(recent_msgs_.​size()​·​>·​max_recent_msgs)​
61 ·​·​·​·​·​·​recent_msgs_.​pop_front()​;​59 ·​·​·​·​·​·​recent_msgs_.​pop_front()​;​
62 60
63 ·​·​·​·​std:​:​for_each(participants​_.​begin()​,​·​participants_.​end()​,​61 ·​·​·​·​for·​(auto·​participant:​·​participants_)​
64 ·​·​·​·​·​·​·​·​boost:​:​bind(&chat_participan​t:​:​deliver,​·​_1,​·​boost:​:​ref(msg)​)​)​;​62 ·​·​·​·​·​·​participant-​>deliver(msg)​;​
65 ·​·​}63 ·​·​}
66 64
67 private:​65 private:​
68 ·​·​std:​:​set<chat_participant_​ptr>·​participants_;​66 ·​·​std:​:​set<chat_participant_​ptr>·​participants_;​
69 ·​·​enum·​{·​max_recent_msgs·​=·​100·​};​67 ·​·​enum·​{·​max_recent_msgs·​=·​100·​};​
70 ·​·​chat_message_queue·​recent_msgs_;​68 ·​·​chat_message_queue·​recent_msgs_;​
71 };​69 };​
72 70
73 /​/​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​71 /​/​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​
74 72
75 class·​chat_session73 class·​chat_session
76 ·​·​:​·​public·​chat_participant,​74 ·​·​:​·​public·​chat_participant,​
77 ·​·​·​·​public·​boost:​:​enable_shared_from_th​is<chat_session>75 ·​·​·​·​public·​std:​:​enable_shared_from_th​is<chat_session>
78 {76 {
79 public:​77 public:​
80 ·​·​chat_session(asio:​:​io_context&·​io_context,​·​chat_room&·​room)​78 ·​·​chat_session(tcp:​:​socket·​socket,​·​chat_room&·​room)​
81 ·​·​·​·​:​·​socket_(io_context)​,​79 ·​·​·​·​:​·​socket_(std:​:​move(socket)​)​,​
82 ·​·​·​·​·​·​room_(room)​80 ·​·​·​·​·​·​room_(room)​
83 ·​·​{81 ·​·​{
84 ·​·​}82 ·​·​}
85 83
86 ·​·​tcp:​:​socket&·​socket()​
87 ·​·​{
88 ·​·​·​·​return·​socket_;​
89 ·​·​}
90
91 ·​·​void·​start()​84 ·​·​void·​start()​
92 ·​·​{85 ·​·​{
93 ·​·​·​·​room_.​join(shared_from_this​()​)​;​86 ·​·​·​·​room_.​join(shared_from_this​()​)​;​
94 ·​·​·​·​asio:​:​async_read(socket_,​87 ·​·​·​·​do_read_header()​;​
95 ·​·​·​·​·​·​·​·​asio:​:​buffer(read_msg_.​data()​,​·​chat_message:​:​header_length)​,​
96 ·​·​·​·​·​·​·​·​boost:​:​bind(
97 ·​·​·​·​·​·​·​·​·​·​&chat_session:​:​handle_read_header,​·​shared_from_this()​,​
98 ·​·​·​·​·​·​·​·​·​·​asio:​:​placeholders:​:​error)​)​;​
99 ·​·​}88 ·​·​}
100 89
101 ·​·​void·​deliver(const·​chat_message&·​msg)​90 ·​·​void·​deliver(const·​chat_message&·​msg)​
102 ·​·​{91 ·​·​{
103 ·​·​·​·​bool·​write_in_progress·​=·​!write_msgs_.​empty()​;​92 ·​·​·​·​bool·​write_in_progress·​=·​!write_msgs_.​empty()​;​
104 ·​·​·​·​write_msgs_.​push_back(msg)​;​93 ·​·​·​·​write_msgs_.​push_back(msg)​;​
105 ·​·​·​·​if·​(!write_in_progress)​94 ·​·​·​·​if·​(!write_in_progress)​
106 ·​·​·​·​{95 ·​·​·​·​{
107 ·​·​·​·​·​·​asio:​:​async_write(socket_,​96 ·​·​·​·​·​·​do_write()​;​
108 ·​·​·​·​·​·​·​·​·​·​asio:​:​buffer(write_msgs_.​front()​.​data()​,​
109 ·​·​·​·​·​·​·​·​·​·​·​·​write_msgs_.​front()​.​length()​)​,​
110 ·​·​·​·​·​·​·​·​·​·​boost:​:​bind(&chat_session:​:​handle_write,​·​shared_from_this()​,​
111 ·​·​·​·​·​·​·​·​·​·​·​·​asio:​:​placeholders:​:​error)​)​;​
112 ·​·​·​·​}97 ·​·​·​·​}
113 ·​·​}98 ·​·​}
114 99
115 ·​·​void·​handle_read_header(co​nst·​asio:​:​error_code&·​error)​100 private:​
116 ·​·​{101 ·​·​void·​do_read_header()​
117 ·​·​·​·​if·​(!error·​&&·​read_msg_.​decode_header()​)​
118 ·​·​·​·​{
119 ·​·​·​·​·​·​asio:​:​async_read(socket_,​
120 ·​·​·​·​·​·​·​·​·​·​asio:​:​buffer(read_msg_.​body()​,​·​read_msg_.​body_length()​)​,​
121 ·​·​·​·​·​·​·​·​·​·​boost:​:​bind(&chat_session:​:​handle_read_body,​·​shared_from_this()​,​
122 ·​·​·​·​·​·​·​·​·​·​·​·​asio:​:​placeholders:​:​error)​)​;​
123 ·​·​·​·​}
124 ·​·​·​·​else
125 ·​·​·​·​{
126 ·​·​·​·​·​·​room_.​leave(shared_from_thi​s()​)​;​
127 ·​·​·​·​}
128 ·​·​}
129
130 ·​·​void·​handle_read_body(cons​t·​asio:​:​error_code&·​error)​
131 ·​·​{102 ·​·​{
132 ·​·​·​·​if·​(!error)​103 ·​·​·​·​auto·​self(shared_from_this​()​)​;​
133 ·​·​·​·​{104 ·​·​·​·​asio:​:​async_read(socket_,​
134 ·​·​·​·​·​·​room_.​deliver(read_msg_)​;​105 ·​·​·​·​·​·​·​·​asio:​:​buffer(read_msg_.​data()​,​·​chat_message:​:​header_length)​,​
135 ·​·​·​·​·​·​asio:​:​async_read(socket_,​106 ·​·​·​·​·​·​·​·​[this,​·​self](std:​:​error_code·​ec,​·​std:​:​size_t·​/​*length*/​)​
136 ·​·​·​·​·​·​·​·​·​·​asio:​:​buffer(read_msg_.​data()​,​·​chat_message:​:​header_length)​,​107 ·​·​·​·​·​·​·​·​{
137 ·​·​·​·​·​·​·​·​·​·​boost:​:​bind(&chat_session:​:​handle_read_header,​·​shared_from_this()​,​108 ·​·​·​·​·​·​·​·​·​·​if·​(!ec·​&&·​read_msg_.​decode_header()​)​
138 ·​·​·​·​·​·​·​·​·​·​·​·​asio:​:​placeholders:​:​error)​)​;​109 ·​·​·​·​·​·​·​·​·​·​{
139 ·​·​·​·​}110 ·​·​·​·​·​·​·​·​·​·​·​·​do_read_body()​;​
140 ·​·​·​·​else111 ·​·​·​·​·​·​·​·​·​·​}
141 ·​·​·​·​{112 ·​·​·​·​·​·​·​·​·​·​else
142 ·​·​·​·​·​·​room_.​leave(shared_from_thi​s()​)​;​113 ·​·​·​·​·​·​·​·​·​·​{
143 ·​·​·​·​}114 ·​·​·​·​·​·​·​·​·​·​·​·​room_.​leave(shared_from_thi​s()​)​;​
115 ·​·​·​·​·​·​·​·​·​·​}
116 ·​·​·​·​·​·​·​·​})​;​
144 ·​·​}117 ·​·​}
145 118
146 ·​·​void·​handle_write(const·​asio:​:​error_code&·​error)​119 ·​·​void·​do_read_body()​
147 ·​·​{120 ·​·​{
148 ·​·​·​·​if·​(!error)​121 ·​·​·​·​auto·​self(shared_from_this​()​)​;​
149 ·​·​·​·​{122 ·​·​·​·​asio:​:​async_read(socket_,​
150 ·​·​·​·​·​·​write_msgs_.​pop_front()​;​123 ·​·​·​·​·​·​·​·​asio:​:​buffer(read_msg_.​body()​,​·​read_msg_.​body_length()​)​,​
151 ·​·​·​·​·​·​if·​(!write_msgs_.​empty()​)​124 ·​·​·​·​·​·​·​·​[this,​·​self](std:​:​error_code·​ec,​·​std:​:​size_t·​/​*length*/​)​
152 ·​·​·​·​·​·​{125 ·​·​·​·​·​·​·​·​{
153 ·​·​·​·​·​·​·​·​asio:​:​async_write(socket_,​126 ·​·​·​·​·​·​·​·​·​·​if·​(!ec)​
154 ·​·​·​·​·​·​·​·​·​·​·​·​asio:​:​buffer(write_msgs_.​front()​.​data()​,​127 ·​·​·​·​·​·​·​·​·​·​{
155 ·​·​·​·​·​·​·​·​·​·​·​·​·​·​write_msgs_.​front()​.​length()​)​,​128 ·​·​·​·​·​·​·​·​·​·​·​·​room_.​deliver(read_msg_)​;​
156 ·​·​·​·​·​·​·​·​·​·​·​·​boost:​:​bind(&chat_session:​:​handle_write,​·​shared_from_this()​,​129 ·​·​·​·​·​·​·​·​·​·​·​·​do_read_header()​;​
157 ·​·​·​·​·​·​·​·​·​·​·​·​·​·​asio:​:​placeholders:​:​error)​)​;​130 ·​·​·​·​·​·​·​·​·​·​}
158 ·​·​·​·​·​·​}131 ·​·​·​·​·​·​·​·​·​·​else
159 ·​·​·​·​}132 ·​·​·​·​·​·​·​·​·​·​{
160 ·​·​·​·​else133 ·​·​·​·​·​·​·​·​·​·​·​·​room_.​leave(shared_from_thi​s()​)​;​
161 ·​·​·​·​{134 ·​·​·​·​·​·​·​·​·​·​}
162 ·​·​·​·​·​·​room_.​leave(shared_from_thi​s()​)​;​135 ·​·​·​·​·​·​·​·​})​;​
163 ·​·​·​·​}136 ·​·​}
137
138 ·​·​void·​do_write()​
139 ·​·​{
140 ·​·​·​·​auto·​self(shared_from_this​()​)​;​
141 ·​·​·​·​asio:​:​async_write(socket_,​
142 ·​·​·​·​·​·​·​·​asio:​:​buffer(write_msgs_.​front()​.​data()​,​
143 ·​·​·​·​·​·​·​·​·​·​write_msgs_.​front()​.​length()​)​,​
144 ·​·​·​·​·​·​·​·​[this,​·​self](std:​:​error_code·​ec,​·​std:​:​size_t·​/​*length*/​)​
145 ·​·​·​·​·​·​·​·​{
146 ·​·​·​·​·​·​·​·​·​·​if·​(!ec)​
147 ·​·​·​·​·​·​·​·​·​·​{
148 ·​·​·​·​·​·​·​·​·​·​·​·​write_msgs_.​pop_front()​;​
149 ·​·​·​·​·​·​·​·​·​·​·​·​if·​(!write_msgs_.​empty()​)​
150 ·​·​·​·​·​·​·​·​·​·​·​·​{
151 ·​·​·​·​·​·​·​·​·​·​·​·​·​·​do_write()​;​
152 ·​·​·​·​·​·​·​·​·​·​·​·​}
153 ·​·​·​·​·​·​·​·​·​·​}
154 ·​·​·​·​·​·​·​·​·​·​else
155 ·​·​·​·​·​·​·​·​·​·​{
156 ·​·​·​·​·​·​·​·​·​·​·​·​room_.​leave(shared_from_thi​s()​)​;​
157 ·​·​·​·​·​·​·​·​·​·​}
158 ·​·​·​·​·​·​·​·​})​;​
164 ·​·​}159 ·​·​}
165 160
166 private:​
167 ·​·​tcp:​:​socket·​socket_;​161 ·​·​tcp:​:​socket·​socket_;​
168 ·​·​chat_room&·​room_;​162 ·​·​chat_room&·​room_;​
169 ·​·​chat_message·​read_msg_;​163 ·​·​chat_message·​read_msg_;​
170 ·​·​chat_message_queue·​write_msgs_;​164 ·​·​chat_message_queue·​write_msgs_;​
171 };​165 };​
172 166
173 typedef·​boost:​:​shared_ptr<chat_sessi​on>·​chat_session_ptr;​
174
175 /​/​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​167 /​/​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​
176 168
177 class·​chat_server169 class·​chat_server
178 {170 {
179 public:​171 public:​
180 ·​·​chat_server(asio:​:​io_context&·​io_context,​172 ·​·​chat_server(asio:​:​io_context&·​io_context,​
181 ·​·​·​·​·​·​const·​tcp:​:​endpoint&·​endpoint)​173 ·​·​·​·​·​·​const·​tcp:​:​endpoint&·​endpoint)​
182 ·​·​·​·​:​·​io_context_(io_contex​t)​,​174 ·​·​·​·​:​·​acceptor_(io_context,​·​endpoint)​
183 ·​·​·​·​·​·​acceptor_(io_context,​·​endpoint)​
184 ·​·​{175 ·​·​{
185 ·​·​·​·​start_accept()​;​176 ·​·​·​·​do_accept()​;​
186 ·​·​}177 ·​·​}
187 178
188 ·​·​void·​start_accept()​179 private:​
189 ·​·​{180 ·​·​void·​do_accept()​
190 ·​·​·​·​chat_session_ptr·​new_session(new·​chat_session(io_conte​xt_,​·​room_)​)​;​
191 ·​·​·​·​acceptor_.​async_accept(new_sess​ion-​>socket()​,​
192 ·​·​·​·​·​·​·​·​boost:​:​bind(&chat_server:​:​handle_accept,​·​this,​·​new_session,​
193 ·​·​·​·​·​·​·​·​·​·​asio:​:​placeholders:​:​error)​)​;​
194 ·​·​}
195
196 ·​·​void·​handle_accept(chat_se​ssion_ptr·​session,​
197 ·​·​·​·​·​·​const·​asio:​:​error_code&·​error)​
198 ·​·​{181 ·​·​{
199 ·​·​·​·​if·​(!error)​182 ·​·​·​·​acceptor_.​async_accept(
200 ·​·​·​·​{183 ·​·​·​·​·​·​·​·​[this](std:​:​error_code·​ec,​·​tcp:​:​socket·​socket)​
201 ·​·​·​·​·​·​session-​>start()​;​184 ·​·​·​·​·​·​·​·​{
202 ·​·​·​·​}185 ·​·​·​·​·​·​·​·​·​·​if·​(!ec)​
186 ·​·​·​·​·​·​·​·​·​·​{
187 ·​·​·​·​·​·​·​·​·​·​·​·​std:​:​make_shared<chat_sess​ion>(std:​:​move(socket)​,​·​room_)​-​>start()​;​
188 ·​·​·​·​·​·​·​·​·​·​}
203 189
204 ·​·​·​·​start_accept()​;​190 ·​·​·​·​·​·​·​·​·​·​do_accept()​;​
191 ·​·​·​·​·​·​·​·​})​;​
205 ·​·​}192 ·​·​}
206 193
207 private:​
208 ·​·​asio:​:​io_context&·​io_context_;​
209 ·​·​tcp:​:​acceptor·​acceptor_;​194 ·​·​tcp:​:​acceptor·​acceptor_;​
210 ·​·​chat_room·​room_;​195 ·​·​chat_room·​room_;​
211 };​196 };​
212 197
213 typedef·​boost:​:​shared_ptr<chat_serve​r>·​chat_server_ptr;​
214 typedef·​std:​:​list<chat_server_ptr>​·​chat_server_list;​
215
216 /​/​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​198 /​/​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​
217 199
218 int·​main(int·​argc,​·​char*·​argv[])​200 int·​main(int·​argc,​·​char*·​argv[])​
219 {201 {
220 ·​·​try202 ·​·​try
221 ·​·​{203 ·​·​{
222 ·​·​·​·​if·​(argc·​<·​2)​204 ·​·​·​·​if·​(argc·​<·​2)​
223 ·​·​·​·​{205 ·​·​·​·​{
224 ·​·​·​·​·​·​std:​:​cerr·​<<·​"Usage:​·​chat_server·​<port>·​[<port>·​.​.​.​]\n";​206 ·​·​·​·​·​·​std:​:​cerr·​<<·​"Usage:​·​chat_server·​<port>·​[<port>·​.​.​.​]\n";​
225 ·​·​·​·​·​·​return·​1;​207 ·​·​·​·​·​·​return·​1;​
226 ·​·​·​·​}208 ·​·​·​·​}
227 209
228 ·​·​·​·​asio:​:​io_context·​io_context;​210 ·​·​·​·​asio:​:​io_context·​io_context;​
229 211
230 ·​·​·​·​chat_server_list·​servers;​212 ·​·​·​·​std:​:​list<chat_server>·​servers;​
231 ·​·​·​·​for·​(int·​i·​=·​1;​·​i·​<·​argc;​·​++i)​213 ·​·​·​·​for·​(int·​i·​=·​1;​·​i·​<·​argc;​·​++i)​
232 ·​·​·​·​{214 ·​·​·​·​{
233 ·​·​·​·​·​·​using·​namespace·​std;​·​/​/​·​For·​atoi.​215 ·​·​·​·​·​·​tcp:​:​endpoint·​endpoint(tcp:​:​v4()​,​·​std:​:​atoi(argv[i])​)​;​
234 ·​·​·​·​·​·​tcp:​:​endpoint·​endpoint(tcp:​:​v4()​,​·​atoi(argv[i])​)​;​216 ·​·​·​·​·​·​servers.​emplace_back(io_conte​xt,​·​endpoint)​;​
235 ·​·​·​·​·​·​chat_server_ptr·​server(new·​chat_server(io_contex​t,​·​endpoint)​)​;​
236 ·​·​·​·​·​·​servers.​push_back(server)​;​
237 ·​·​·​·​}217 ·​·​·​·​}
238 218
239 ·​·​·​·​io_context.​run()​;​219 ·​·​·​·​io_context.​run()​;​
240 ·​·​}220 ·​·​}
241 ·​·​catch·​(std:​:​exception&·​e)​221 ·​·​catch·​(std:​:​exception&·​e)​
242 ·​·​{222 ·​·​{
243 ·​·​·​·​std:​:​cerr·​<<·​"Exception:​·​"·​<<·​e.​what()​·​<<·​"\n";​223 ·​·​·​·​std:​:​cerr·​<<·​"Exception:​·​"·​<<·​e.​what()​·​<<·​"\n";​
244 ·​·​}224 ·​·​}
245 225
246 ·​·​return·​0;​226 ·​·​return·​0;​
247 }227 }