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