src/​examples/​cpp03/​spawn/​echo_server.​cppsrc/​examples/​cpp11/​spawn/​echo_server.​cpp
⋮⋮
1 /​/​1 /​/​
2 /​/​·​echo_server.​cpp2 /​/​·​echo_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·​<asio/​deadline_timer.​hpp>
12 #include·​<asio/​io_service.​hpp>11 #include·​<asio/​io_service.​hpp>
13 #include·​<asio/​ip/​tcp.​hpp>12 #include·​<asio/​ip/​tcp.​hpp>
14 #include·​<asio/​spawn.​hpp>13 #include·​<asio/​spawn.​hpp>
14 #include·​<asio/​steady_timer.​hpp>
15 #include·​<asio/​write.​hpp>15 #include·​<asio/​write.​hpp>
16 #include·​<boost/​bind.​hpp>
17 #include·​<boost/​shared_ptr.​hpp>
18 #include·​<boost/​enable_shared_from_th​is.​hpp>
19 #include·​<iostream>16 #include·​<iostream>
17 #include·​<memory>
20 18
21 using·​asio:​:​ip:​:​tcp;​19 using·​asio:​:​ip:​:​tcp;​
22 20
23 class·​session·​:​·​public·​boost:​:​enable_shared_from_th​is<session>21 class·​session·​:​·​public·​std:​:​enable_shared_from_th​is<session>
24 {22 {
25 public:​23 public:​
26 ·​·​explicit·​session(asio:​:​io_service&·​io_service)​24 ·​·​explicit·​session(tcp:​:​socket·​socket)​
27 ·​·​·​·​:​·​strand_(io_service)​,​25 ·​·​·​·​:​·​socket_(std:​:​move(socket)​)​,​
28 ·​·​·​·​·​·​socket_(io_service)​,​26 ·​·​·​·​·​·​timer_(socket_.​get_io_service()​)​,​
29 ·​·​·​·​·​·​timer_(io_service)​27 ·​·​·​·​·​·​strand_(socket_.​get_io_service()​)​
30 ·​·​{28 ·​·​{
31 ·​·​}29 ·​·​}
32 30
33 ·​·​tcp:​:​socket&·​socket()​
34 ·​·​{
35 ·​·​·​·​return·​socket_;​
36 ·​·​}
37
38 ·​·​void·​go()​31 ·​·​void·​go()​
39 ·​·​{32 ·​·​{
33 ·​·​·​·​auto·​self(shared_from_this​()​)​;​
40 ·​·​·​·​asio:​:​spawn(strand_,​34 ·​·​·​·​asio:​:​spawn(strand_,​
41 ·​·​·​·​·​·​·​·​boost:​:​bind(&session:​:​echo,​35 ·​·​·​·​·​·​·​·​[this,​·​self](asio:​:​yield_context·​yield)​
42 ·​·​·​·​·​·​·​·​·​·​shared_from_this()​,​·​_1)​)​;​36 ·​·​·​·​·​·​·​·​{
37 ·​·​·​·​·​·​·​·​·​·​try
38 ·​·​·​·​·​·​·​·​·​·​{
39 ·​·​·​·​·​·​·​·​·​·​·​·​char·​data[128];​
40 ·​·​·​·​·​·​·​·​·​·​·​·​for·​(;​;​)​
41 ·​·​·​·​·​·​·​·​·​·​·​·​{
42 ·​·​·​·​·​·​·​·​·​·​·​·​·​·​timer_.​expires_from_now(std:​:​chrono:​:​seconds(10)​)​;​
43 ·​·​·​·​·​·​·​·​·​·​·​·​·​·​std:​:​size_t·​n·​=·​socket_.​async_read_some(asio:​:​buffer(data)​,​·​yield)​;​
44 ·​·​·​·​·​·​·​·​·​·​·​·​·​·​asio:​:​async_write(socket_,​·​asio:​:​buffer(data,​·​n)​,​·​yield)​;​
45 ·​·​·​·​·​·​·​·​·​·​·​·​}
46 ·​·​·​·​·​·​·​·​·​·​}
47 ·​·​·​·​·​·​·​·​·​·​catch·​(std:​:​exception&·​e)​
48 ·​·​·​·​·​·​·​·​·​·​{
49 ·​·​·​·​·​·​·​·​·​·​·​·​socket_.​close()​;​
50 ·​·​·​·​·​·​·​·​·​·​·​·​timer_.​cancel()​;​
51 ·​·​·​·​·​·​·​·​·​·​}
52 ·​·​·​·​·​·​·​·​})​;​
53
43 ·​·​·​·​asio:​:​spawn(strand_,​54 ·​·​·​·​asio:​:​spawn(strand_,​
44 ·​·​·​·​·​·​·​·​boost:​:​bind(&session:​:​timeout,​55 ·​·​·​·​·​·​·​·​[this,​·​self](asio:​:​yield_context·​yield)​
45 ·​·​·​·​·​·​·​·​·​·​shared_from_this()​,​·​_1)​)​;​56 ·​·​·​·​·​·​·​·​{
57 ·​·​·​·​·​·​·​·​·​·​while·​(socket_.​is_open()​)​
58 ·​·​·​·​·​·​·​·​·​·​{
59 ·​·​·​·​·​·​·​·​·​·​·​·​asio:​:​error_code·​ignored_ec;​
60 ·​·​·​·​·​·​·​·​·​·​·​·​timer_.​async_wait(yield[igno​red_ec])​;​
61 ·​·​·​·​·​·​·​·​·​·​·​·​if·​(timer_.​expires_from_now()​·​<=·​std:​:​chrono:​:​seconds(0)​)​
62 ·​·​·​·​·​·​·​·​·​·​·​·​·​·​socket_.​close()​;​
63 ·​·​·​·​·​·​·​·​·​·​}
64 ·​·​·​·​·​·​·​·​})​;​
46 ·​·​}65 ·​·​}
47 66
48 private:​67 private:​
49 ·​·​void·​echo(asio:​:​yield_context·​yield)​
50 ·​·​{
51 ·​·​·​·​try
52 ·​·​·​·​{
53 ·​·​·​·​·​·​char·​data[128];​
54 ·​·​·​·​·​·​for·​(;​;​)​
55 ·​·​·​·​·​·​{
56 ·​·​·​·​·​·​·​·​timer_.​expires_from_now(boos​t:​:​posix_time:​:​seconds(10)​)​;​
57 ·​·​·​·​·​·​·​·​std:​:​size_t·​n·​=·​socket_.​async_read_some(asio:​:​buffer(data)​,​·​yield)​;​
58 ·​·​·​·​·​·​·​·​asio:​:​async_write(socket_,​·​asio:​:​buffer(data,​·​n)​,​·​yield)​;​
59 ·​·​·​·​·​·​}
60 ·​·​·​·​}
61 ·​·​·​·​catch·​(std:​:​exception&·​e)​
62 ·​·​·​·​{
63 ·​·​·​·​·​·​socket_.​close()​;​
64 ·​·​·​·​·​·​timer_.​cancel()​;​
65 ·​·​·​·​}
66 ·​·​}
67
68 ·​·​void·​timeout(asio:​:​yield_context·​yield)​
69 ·​·​{
70 ·​·​·​·​while·​(socket_.​is_open()​)​
71 ·​·​·​·​{
72 ·​·​·​·​·​·​asio:​:​error_code·​ignored_ec;​
73 ·​·​·​·​·​·​timer_.​async_wait(yield[igno​red_ec])​;​
74 ·​·​·​·​·​·​if·​(timer_.​expires_from_now()​·​<=·​boost:​:​posix_time:​:​seconds(0)​)​
75 ·​·​·​·​·​·​·​·​socket_.​close()​;​
76 ·​·​·​·​}
77 ·​·​}
78
79 ·​·​asio:​:​io_service:​:​strand·​strand_;​
80 ·​·​tcp:​:​socket·​socket_;​68 ·​·​tcp:​:​socket·​socket_;​
81 ·​·​asio:​:​deadline_timer·​timer_;​69 ·​·​asio:​:​steady_timer·​timer_;​
70 ·​·​asio:​:​io_service:​:​strand·​strand_;​
82 };​71 };​
83 72
84 void·​do_accept(asio:​:​io_service&·​io_service,​
85 ·​·​·​·​unsigned·​short·​port,​·​asio:​:​yield_context·​yield)​
86 {
87 ·​·​tcp:​:​acceptor·​acceptor(io_service,​·​tcp:​:​endpoint(tcp:​:​v4()​,​·​port)​)​;​
88
89 ·​·​for·​(;​;​)​
90 ·​·​{
91 ·​·​·​·​asio:​:​error_code·​ec;​
92 ·​·​·​·​boost:​:​shared_ptr<session>·​new_session(new·​session(io_service)​)​;​
93 ·​·​·​·​acceptor.​async_accept(new_sess​ion-​>socket()​,​·​yield[ec])​;​
94 ·​·​·​·​if·​(!ec)​·​new_session-​>go()​;​
95 ·​·​}
96 }
97
98 int·​main(int·​argc,​·​char*·​argv[])​73 int·​main(int·​argc,​·​char*·​argv[])​
99 {74 {
100 ·​·​try75 ·​·​try
101 ·​·​{76 ·​·​{
102 ·​·​·​·​if·​(argc·​!=·​2)​77 ·​·​·​·​if·​(argc·​!=·​2)​
103 ·​·​·​·​{78 ·​·​·​·​{
104 ·​·​·​·​·​·​std:​:​cerr·​<<·​"Usage:​·​echo_server·​<port>\n";​79 ·​·​·​·​·​·​std:​:​cerr·​<<·​"Usage:​·​echo_server·​<port>\n";​
105 ·​·​·​·​·​·​return·​1;​80 ·​·​·​·​·​·​return·​1;​
106 ·​·​·​·​}81 ·​·​·​·​}
107 82
108 ·​·​·​·​asio:​:​io_service·​io_service;​83 ·​·​·​·​asio:​:​io_service·​io_service;​
109 84
110 ·​·​·​·​asio:​:​spawn(io_service,​85 ·​·​·​·​asio:​:​spawn(io_service,​
111 ·​·​·​·​·​·​·​·​boost:​:​bind(do_accept,​86 ·​·​·​·​·​·​·​·​[&](asio:​:​yield_context·​yield)​
112 ·​·​·​·​·​·​·​·​·​·​boost:​:​ref(io_service)​,​·​atoi(argv[1])​,​·​_1)​)​;​87 ·​·​·​·​·​·​·​·​{
88 ·​·​·​·​·​·​·​·​·​·​tcp:​:​acceptor·​acceptor(io_service,​
89 ·​·​·​·​·​·​·​·​·​·​·​·​tcp:​:​endpoint(tcp:​:​v4()​,​·​std:​:​atoi(argv[1])​)​)​;​
90
91 ·​·​·​·​·​·​·​·​·​·​for·​(;​;​)​
92 ·​·​·​·​·​·​·​·​·​·​{
93 ·​·​·​·​·​·​·​·​·​·​·​·​asio:​:​error_code·​ec;​
94 ·​·​·​·​·​·​·​·​·​·​·​·​tcp:​:​socket·​socket(io_service)​;​
95 ·​·​·​·​·​·​·​·​·​·​·​·​acceptor.​async_accept(socket,​·​yield[ec])​;​
96 ·​·​·​·​·​·​·​·​·​·​·​·​if·​(!ec)​·​std:​:​make_shared<session>(​std:​:​move(socket)​)​-​>go()​;​
97 ·​·​·​·​·​·​·​·​·​·​}
98 ·​·​·​·​·​·​·​·​})​;​
113 99
114 ·​·​·​·​io_service.​run()​;​100 ·​·​·​·​io_service.​run()​;​
115 ·​·​}101 ·​·​}
116 ·​·​catch·​(std:​:​exception&·​e)​102 ·​·​catch·​(std:​:​exception&·​e)​
117 ·​·​{103 ·​·​{
118 ·​·​·​·​std:​:​cerr·​<<·​"Exception:​·​"·​<<·​e.​what()​·​<<·​"\n";​104 ·​·​·​·​std:​:​cerr·​<<·​"Exception:​·​"·​<<·​e.​what()​·​<<·​"\n";​
119 ·​·​}105 ·​·​}
120 106
121 ·​·​return·​0;​107 ·​·​return·​0;​
122 }108 }