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-​2016·​Christopher·​M.​·​Kohlhoff·​(chris·​at·​kohlhoff·​dot·​com)​5 /​/​·​Copyright·​(c)​·​2003-​2016·​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_service&·​io_service,​·​chat_room&·​room)​78 ·​·​chat_session(tcp:​:​socket·​socket,​·​chat_room&·​room)​
81 ·​·​·​·​:​·​socket_(io_service)​,​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 ·​·​·​·​}
113 ·​·​}
114
115 ·​·​void·​handle_read_header(co​nst·​asio:​:​error_code&·​error)​
116 ·​·​{
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 ·​·​·​·​}97 ·​·​·​·​}
128 ·​·​}98 ·​·​}
129 99
130 ·​·​void·​handle_read_body(cons​t·​asio:​:​error_code&·​error)​100 private:​
101 ·​·​void·​do_read_header()​
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_service&·​io_service,​172 ·​·​chat_server(asio:​:​io_service&·​io_service,​
181 ·​·​·​·​·​·​const·​tcp:​:​endpoint&·​endpoint)​173 ·​·​·​·​·​·​const·​tcp:​:​endpoint&·​endpoint)​
182 ·​·​·​·​:​·​io_service_(io_servic​e)​,​174 ·​·​·​·​:​·​acceptor_(io_service,​·​endpoint)​,​
183 ·​·​·​·​·​·​acceptor_(io_service,​·​endpoint)​175 ·​·​·​·​·​·​socket_(io_service)​
184 ·​·​{176 ·​·​{
185 ·​·​·​·​start_accept()​;​177 ·​·​·​·​do_accept()​;​
186 ·​·​}178 ·​·​}
187 179
188 ·​·​void·​start_accept()​180 private:​
189 ·​·​{181 ·​·​void·​do_accept()​
190 ·​·​·​·​chat_session_ptr·​new_session(new·​chat_session(io_servi​ce_,​·​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 ·​·​{182 ·​·​{
199 ·​·​·​·​if·​(!error)​183 ·​·​·​·​acceptor_.​async_accept(socket_,​
200 ·​·​·​·​{184 ·​·​·​·​·​·​·​·​[this](std:​:​error_code·​ec)​
201 ·​·​·​·​·​·​session-​>start()​;​185 ·​·​·​·​·​·​·​·​{
202 ·​·​·​·​}186 ·​·​·​·​·​·​·​·​·​·​if·​(!ec)​
187 ·​·​·​·​·​·​·​·​·​·​{
188 ·​·​·​·​·​·​·​·​·​·​·​·​std:​:​make_shared<chat_sess​ion>(std:​:​move(socket_)​,​·​room_)​-​>start()​;​
189 ·​·​·​·​·​·​·​·​·​·​}
203 190
204 ·​·​·​·​start_accept()​;​191 ·​·​·​·​·​·​·​·​·​·​do_accept()​;​
192 ·​·​·​·​·​·​·​·​})​;​
205 ·​·​}193 ·​·​}
206 194
207 private:​
208 ·​·​asio:​:​io_service&·​io_service_;​
209 ·​·​tcp:​:​acceptor·​acceptor_;​195 ·​·​tcp:​:​acceptor·​acceptor_;​
196 ·​·​tcp:​:​socket·​socket_;​
210 ·​·​chat_room·​room_;​197 ·​·​chat_room·​room_;​
211 };​198 };​
212 199
213 typedef·​boost:​:​shared_ptr<chat_serve​r>·​chat_server_ptr;​
214 typedef·​std:​:​list<chat_server_ptr>​·​chat_server_list;​
215
216 /​/​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​200 /​/​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​
217 201
218 int·​main(int·​argc,​·​char*·​argv[])​202 int·​main(int·​argc,​·​char*·​argv[])​
219 {203 {
220 ·​·​try204 ·​·​try
221 ·​·​{205 ·​·​{
222 ·​·​·​·​if·​(argc·​<·​2)​206 ·​·​·​·​if·​(argc·​<·​2)​
223 ·​·​·​·​{207 ·​·​·​·​{
224 ·​·​·​·​·​·​std:​:​cerr·​<<·​"Usage:​·​chat_server·​<port>·​[<port>·​.​.​.​]\n";​208 ·​·​·​·​·​·​std:​:​cerr·​<<·​"Usage:​·​chat_server·​<port>·​[<port>·​.​.​.​]\n";​
225 ·​·​·​·​·​·​return·​1;​209 ·​·​·​·​·​·​return·​1;​
226 ·​·​·​·​}210 ·​·​·​·​}
227 211
228 ·​·​·​·​asio:​:​io_service·​io_service;​212 ·​·​·​·​asio:​:​io_service·​io_service;​
229 213
230 ·​·​·​·​chat_server_list·​servers;​214 ·​·​·​·​std:​:​list<chat_server>·​servers;​
231 ·​·​·​·​for·​(int·​i·​=·​1;​·​i·​<·​argc;​·​++i)​215 ·​·​·​·​for·​(int·​i·​=·​1;​·​i·​<·​argc;​·​++i)​
232 ·​·​·​·​{216 ·​·​·​·​{
233 ·​·​·​·​·​·​using·​namespace·​std;​·​/​/​·​For·​atoi.​217 ·​·​·​·​·​·​tcp:​:​endpoint·​endpoint(tcp:​:​v4()​,​·​std:​:​atoi(argv[i])​)​;​
234 ·​·​·​·​·​·​tcp:​:​endpoint·​endpoint(tcp:​:​v4()​,​·​atoi(argv[i])​)​;​218 ·​·​·​·​·​·​servers.​emplace_back(io_servi​ce,​·​endpoint)​;​
235 ·​·​·​·​·​·​chat_server_ptr·​server(new·​chat_server(io_servic​e,​·​endpoint)​)​;​
236 ·​·​·​·​·​·​servers.​push_back(server)​;​
237 ·​·​·​·​}219 ·​·​·​·​}
238 220
239 ·​·​·​·​io_service.​run()​;​221 ·​·​·​·​io_service.​run()​;​
240 ·​·​}222 ·​·​}
241 ·​·​catch·​(std:​:​exception&·​e)​223 ·​·​catch·​(std:​:​exception&·​e)​
242 ·​·​{224 ·​·​{
243 ·​·​·​·​std:​:​cerr·​<<·​"Exception:​·​"·​<<·​e.​what()​·​<<·​"\n";​225 ·​·​·​·​std:​:​cerr·​<<·​"Exception:​·​"·​<<·​e.​what()​·​<<·​"\n";​
244 ·​·​}226 ·​·​}
245 227
246 ·​·​return·​0;​228 ·​·​return·​0;​
247 }229 }