src/​examples/​cpp03/​timeouts/​blocking_udp_client.​cppsrc/​examples/​cpp11/​timeouts/​blocking_udp_client.​cpp
⋮⋮
1 /​/​1 /​/​
2 /​/​·​blocking_udp_client.​cpp2 /​/​·​blocking_udp_client.​cpp
3 /​/​·​~~~~~~~~~~~~~~~~~~~~~​~~3 /​/​·​~~~~~~~~~~~~~~~~~~~~~​~~
4 /​/​4 /​/​
5 /​/​·​Copyright·​(c)​·​2003-​2022·​Christopher·​M.​·​Kohlhoff·​(chris·​at·​kohlhoff·​dot·​com)​5 /​/​·​Copyright·​(c)​·​2003-​2022·​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/​buffer.​hpp"11 #include·​"asio/​buffer.​hpp"
12 #include·​"asio/​io_context.​hpp"12 #include·​"asio/​io_context.​hpp"
13 #include·​"asio/​ip/​udp.​hpp"13 #include·​"asio/​ip/​udp.​hpp"
14 #include·​<cstdlib>14 #include·​<cstdlib>
15 #include·​<boost/​bind/​bind.​hpp>15 #include·​<functional>
16 #include·​<iostream>16 #include·​<iostream>
17 17
18 using·​asio:​:​ip:​:​udp;​18 using·​asio:​:​ip:​:​udp;​
19 using·​std:​:​placeholders:​:​_1;​
20 using·​std:​:​placeholders:​:​_2;​
19 21
20 /​/​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​22 /​/​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​
21 23
22 /​/​24 /​/​
23 /​/​·​This·​class·​manages·​socket·​timeouts·​by·​running·​the·​io_context·​using·​the·​timed25 /​/​·​This·​class·​manages·​socket·​timeouts·​by·​running·​the·​io_context·​using·​the·​timed
24 /​/​·​io_context:​:​run_for()​·​member·​function.​·​Each·​asynchronous·​operation·​is·​given26 /​/​·​io_context:​:​run_for()​·​member·​function.​·​Each·​asynchronous·​operation·​is·​given
25 /​/​·​a·​timeout·​within·​which·​it·​must·​complete.​·​The·​socket·​operations·​themselves27 /​/​·​a·​timeout·​within·​which·​it·​must·​complete.​·​The·​socket·​operations·​themselves
26 /​/​·​use·​boost:​:​bind·​to·​specify·​the·​completion·​handler:​28 /​/​·​use·​std:​:​bind·​to·​specify·​the·​completion·​handler:​
27 /​/​29 /​/​
28 /​/​·​·​·​+-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​+30 /​/​·​·​·​+-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​+
29 /​/​·​·​·​|·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​|31 /​/​·​·​·​|·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​|
30 /​/​·​·​·​|·​·​·​·​receive·​·​·​·​|32 /​/​·​·​·​|·​·​·​·​receive·​·​·​·​|
31 /​/​·​·​·​|·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​|33 /​/​·​·​·​|·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​|
32 /​/​·​·​·​+-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​+34 /​/​·​·​·​+-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​+
33 /​/​·​·​·​·​·​·​·​·​·​·​·​|35 /​/​·​·​·​·​·​·​·​·​·​·​·​|
34 /​/​·​·​async_-​·​·​|·​·​·​·​+-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​+36 /​/​·​·​async_-​·​·​|·​·​·​·​+-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​+
35 /​/​·​receive()​·​|·​·​·​·​|·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​|37 /​/​·​receive()​·​|·​·​·​·​|·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​|
36 /​/​·​·​·​·​·​·​·​·​·​·​·​+-​-​-​>|·​handle_receive·​|38 /​/​·​·​·​·​·​·​·​·​·​·​·​+-​-​-​>|·​handle_receive·​|
37 /​/​·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​|·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​|39 /​/​·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​|·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​|
38 /​/​·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​+-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​+40 /​/​·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​·​+-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​+
39 /​/​41 /​/​
40 /​/​·​For·​a·​given·​socket·​operation,​·​the·​client·​object·​runs·​the·​io_context·​to·​block42 /​/​·​For·​a·​given·​socket·​operation,​·​the·​client·​object·​runs·​the·​io_context·​to·​block
41 /​/​·​thread·​execution·​until·​the·​operation·​completes·​or·​the·​timeout·​is·​reached.​·​If43 /​/​·​thread·​execution·​until·​the·​operation·​completes·​or·​the·​timeout·​is·​reached.​·​If
42 /​/​·​the·​io_context:​:​run_for()​·​function·​times·​out,​·​the·​socket·​is·​closed·​and·​the44 /​/​·​the·​io_context:​:​run_for()​·​function·​times·​out,​·​the·​socket·​is·​closed·​and·​the
43 /​/​·​outstanding·​asynchronous·​operation·​is·​cancelled.​45 /​/​·​outstanding·​asynchronous·​operation·​is·​cancelled.​
44 /​/​46 /​/​
45 class·​client47 class·​client
46 {48 {
47 public:​49 public:​
48 ·​·​client(const·​udp:​:​endpoint&·​listen_endpoint)​50 ·​·​client(const·​udp:​:​endpoint&·​listen_endpoint)​
49 ·​·​·​·​:​·​socket_(io_context_,​·​listen_endpoint)​51 ·​·​·​·​:​·​socket_(io_context_,​·​listen_endpoint)​
50 ·​·​{52 ·​·​{
51 ·​·​}53 ·​·​}
52 54
53 ·​·​std:​:​size_t·​receive(const·​asio:​:​mutable_buffer&·​buffer,​55 ·​·​std:​:​size_t·​receive(const·​asio:​:​mutable_buffer&·​buffer,​
54 ·​·​·​·​·​·​asio:​:​chrono:​:​steady_clock:​:​duration·​timeout,​56 ·​·​·​·​·​·​std:​:​chrono:​:​steady_clock:​:​duration·​timeout,​
55 ·​·​·​·​·​·​asio:​:​error_code&·​ec)​57 ·​·​·​·​·​·​std:​:​error_code&·​error)​
56 ·​·​{58 ·​·​{
57 ·​·​·​·​/​/​·​Start·​the·​asynchronous·​operation.​·​The·​handle_receive·​function·​used·​as·​a59 ·​·​·​·​/​/​·​Start·​the·​asynchronous·​operation.​·​The·​handle_receive·​function·​used·​as·​a
58 ·​·​·​·​/​/​·​callback·​will·​update·​the·​ec·​and·​length·​variables.​60 ·​·​·​·​/​/​·​callback·​will·​update·​the·​error·​and·​length·​variables.​
59 ·​·​·​·​std:​:​size_t·​length·​=·​0;​61 ·​·​·​·​std:​:​size_t·​length·​=·​0;​
60 ·​·​·​·​socket_.​async_receive(asio:​:​buffer(buffer)​,​62 ·​·​·​·​socket_.​async_receive(asio:​:​buffer(buffer)​,​
61 ·​·​·​·​·​·​·​·​boost:​:​bind(&client:​:​handle_receive,​63 ·​·​·​·​·​·​·​·​std:​:​bind(&client:​:​handle_receive,​·​_1,​·​_2,​·​&error,​·​&length)​)​;​
62 ·​·​·​·​·​·​·​·​·​·​boost:​:​placeholders:​:​_1,​·​boost:​:​placeholders:​:​_2,​·​&ec,​·​&length)​)​;​
63 64
64 ·​·​·​·​/​/​·​Run·​the·​operation·​until·​it·​completes,​·​or·​until·​the·​timeout.​65 ·​·​·​·​/​/​·​Run·​the·​operation·​until·​it·​completes,​·​or·​until·​the·​timeout.​
65 ·​·​·​·​run(timeout)​;​66 ·​·​·​·​run(timeout)​;​
66 67
67 ·​·​·​·​return·​length;​68 ·​·​·​·​return·​length;​
68 ·​·​}69 ·​·​}
69 70
70 private:​71 private:​
71 ·​·​void·​run(asio:​:​chrono:​:​steady_clock:​:​duration·​timeout)​72 ·​·​void·​run(std:​:​chrono:​:​steady_clock:​:​duration·​timeout)​
72 ·​·​{73 ·​·​{
73 ·​·​·​·​/​/​·​Restart·​the·​io_context,​·​as·​it·​may·​have·​been·​left·​in·​the·​"stopped"·​state74 ·​·​·​·​/​/​·​Restart·​the·​io_context,​·​as·​it·​may·​have·​been·​left·​in·​the·​"stopped"·​state
74 ·​·​·​·​/​/​·​by·​a·​previous·​operation.​75 ·​·​·​·​/​/​·​by·​a·​previous·​operation.​
75 ·​·​·​·​io_context_.​restart()​;​76 ·​·​·​·​io_context_.​restart()​;​
76 77
77 ·​·​·​·​/​/​·​Block·​until·​the·​asynchronous·​operation·​has·​completed,​·​or·​timed·​out.​·​If78 ·​·​·​·​/​/​·​Block·​until·​the·​asynchronous·​operation·​has·​completed,​·​or·​timed·​out.​·​If
78 ·​·​·​·​/​/​·​the·​pending·​asynchronous·​operation·​is·​a·​composed·​operation,​·​the·​deadline79 ·​·​·​·​/​/​·​the·​pending·​asynchronous·​operation·​is·​a·​composed·​operation,​·​the·​deadline
79 ·​·​·​·​/​/​·​applies·​to·​the·​entire·​operation,​·​rather·​than·​individual·​operations·​on80 ·​·​·​·​/​/​·​applies·​to·​the·​entire·​operation,​·​rather·​than·​individual·​operations·​on
80 ·​·​·​·​/​/​·​the·​socket.​81 ·​·​·​·​/​/​·​the·​socket.​
81 ·​·​·​·​io_context_.​run_for(timeout)​;​82 ·​·​·​·​io_context_.​run_for(timeout)​;​
82 83
83 ·​·​·​·​/​/​·​If·​the·​asynchronous·​operation·​completed·​successfully·​then·​the·​io_context84 ·​·​·​·​/​/​·​If·​the·​asynchronous·​operation·​completed·​successfully·​then·​the·​io_context
84 ·​·​·​·​/​/​·​would·​have·​been·​stopped·​due·​to·​running·​out·​of·​work.​·​If·​it·​was·​not85 ·​·​·​·​/​/​·​would·​have·​been·​stopped·​due·​to·​running·​out·​of·​work.​·​If·​it·​was·​not
85 ·​·​·​·​/​/​·​stopped,​·​then·​the·​io_context:​:​run_for·​call·​must·​have·​timed·​out.​86 ·​·​·​·​/​/​·​stopped,​·​then·​the·​io_context:​:​run_for·​call·​must·​have·​timed·​out.​
86 ·​·​·​·​if·​(!io_context_.​stopped()​)​87 ·​·​·​·​if·​(!io_context_.​stopped()​)​
87 ·​·​·​·​{88 ·​·​·​·​{
88 ·​·​·​·​·​·​/​/​·​Cancel·​the·​outstanding·​asynchronous·​operation.​89 ·​·​·​·​·​·​/​/​·​Cancel·​the·​outstanding·​asynchronous·​operation.​
89 ·​·​·​·​·​·​socket_.​cancel()​;​90 ·​·​·​·​·​·​socket_.​cancel()​;​
90 91
91 ·​·​·​·​·​·​/​/​·​Run·​the·​io_context·​again·​until·​the·​operation·​completes.​92 ·​·​·​·​·​·​/​/​·​Run·​the·​io_context·​again·​until·​the·​operation·​completes.​
92 ·​·​·​·​·​·​io_context_.​run()​;​93 ·​·​·​·​·​·​io_context_.​run()​;​
93 ·​·​·​·​}94 ·​·​·​·​}
94 ·​·​}95 ·​·​}
95 96
96 ·​·​static·​void·​handle_receive(97 ·​·​static·​void·​handle_receive(
97 ·​·​·​·​·​·​const·​asio:​:​error_code&·​ec,​·​std:​:​size_t·​length,​98 ·​·​·​·​·​·​const·​std:​:​error_code&·​error,​·​std:​:​size_t·​length,​
98 ·​·​·​·​·​·​asio:​:​error_code*·​out_ec,​·​std:​:​size_t*·​out_length)​99 ·​·​·​·​·​·​std:​:​error_code*·​out_error,​·​std:​:​size_t*·​out_length)​
99 ·​·​{100 ·​·​{
100 ·​·​·​·​*out_ec·​=·​ec;​101 ·​·​·​·​*out_error·​=·​error;​
101 ·​·​·​·​*out_length·​=·​length;​102 ·​·​·​·​*out_length·​=·​length;​
102 ·​·​}103 ·​·​}
103 104
104 private:​105 private:​
105 ·​·​asio:​:​io_context·​io_context_;​106 ·​·​asio:​:​io_context·​io_context_;​
106 ·​·​udp:​:​socket·​socket_;​107 ·​·​udp:​:​socket·​socket_;​
107 };​108 };​
108 109
109 /​/​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​110 /​/​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​
110 111
111 int·​main(int·​argc,​·​char*·​argv[])​112 int·​main(int·​argc,​·​char*·​argv[])​
112 {113 {
113 ·​·​try114 ·​·​try
114 ·​·​{115 ·​·​{
115 ·​·​·​·​using·​namespace·​std;​·​/​/​·​For·​atoi.​116 ·​·​·​·​using·​namespace·​std;​·​/​/​·​For·​atoi.​
116 117
117 ·​·​·​·​if·​(argc·​!=·​3)​118 ·​·​·​·​if·​(argc·​!=·​3)​
118 ·​·​·​·​{119 ·​·​·​·​{
119 ·​·​·​·​·​·​std:​:​cerr·​<<·​"Usage:​·​blocking_udp_client·​<listen_addr>·​<listen_port>\n";​120 ·​·​·​·​·​·​std:​:​cerr·​<<·​"Usage:​·​blocking_udp_client·​<listen_addr>·​<listen_port>\n";​
120 ·​·​·​·​·​·​return·​1;​121 ·​·​·​·​·​·​return·​1;​
121 ·​·​·​·​}122 ·​·​·​·​}
122 123
123 ·​·​·​·​udp:​:​endpoint·​listen_endpoint(124 ·​·​·​·​udp:​:​endpoint·​listen_endpoint(
124 ·​·​·​·​·​·​·​·​asio:​:​ip:​:​make_address(argv[1])​,​125 ·​·​·​·​·​·​·​·​asio:​:​ip:​:​make_address(argv[1])​,​
125 ·​·​·​·​·​·​·​·​std:​:​atoi(argv[2])​)​;​126 ·​·​·​·​·​·​·​·​std:​:​atoi(argv[2])​)​;​
126 127
127 ·​·​·​·​client·​c(listen_endpoint)​;​128 ·​·​·​·​client·​c(listen_endpoint)​;​
128 129
129 ·​·​·​·​for·​(;​;​)​130 ·​·​·​·​for·​(;​;​)​
130 ·​·​·​·​{131 ·​·​·​·​{
131 ·​·​·​·​·​·​char·​data[1024];​132 ·​·​·​·​·​·​char·​data[1024];​
132 ·​·​·​·​·​·​asio:​:​error_code·​ec;​133 ·​·​·​·​·​·​std:​:​error_code·​error;​
133 ·​·​·​·​·​·​std:​:​size_t·​n·​=·​c.​receive(asio:​:​buffer(data)​,​134 ·​·​·​·​·​·​std:​:​size_t·​n·​=·​c.​receive(asio:​:​buffer(data)​,​
134 ·​·​·​·​·​·​·​·​·​·​asio:​:​chrono:​:​seconds(10)​,​·​ec)​;​135 ·​·​·​·​·​·​·​·​·​·​std:​:​chrono:​:​seconds(10)​,​·​error)​;​
135 136
136 ·​·​·​·​·​·​if·​(ec)​137 ·​·​·​·​·​·​if·​(error)​
137 ·​·​·​·​·​·​{138 ·​·​·​·​·​·​{
138 ·​·​·​·​·​·​·​·​std:​:​cout·​<<·​"Receive·​error:​·​"·​<<·​ec.​message()​·​<<·​"\n";​·​139 ·​·​·​·​·​·​·​·​std:​:​cout·​<<·​"Receive·​error:​·​"·​<<·​error.​message()​·​<<·​"\n";​·​
139 ·​·​·​·​·​·​}140 ·​·​·​·​·​·​}
140 ·​·​·​·​·​·​else141 ·​·​·​·​·​·​else
141 ·​·​·​·​·​·​{142 ·​·​·​·​·​·​{
142 ·​·​·​·​·​·​·​·​std:​:​cout·​<<·​"Received:​·​";​143 ·​·​·​·​·​·​·​·​std:​:​cout·​<<·​"Received:​·​";​
143 ·​·​·​·​·​·​·​·​std:​:​cout.​write(data,​·​n)​;​144 ·​·​·​·​·​·​·​·​std:​:​cout.​write(data,​·​n)​;​
144 ·​·​·​·​·​·​·​·​std:​:​cout·​<<·​"\n";​145 ·​·​·​·​·​·​·​·​std:​:​cout·​<<·​"\n";​
145 ·​·​·​·​·​·​}146 ·​·​·​·​·​·​}
146 ·​·​·​·​}147 ·​·​·​·​}
147 ·​·​}148 ·​·​}
148 ·​·​catch·​(std:​:​exception&·​e)​149 ·​·​catch·​(std:​:​exception&·​e)​
149 ·​·​{150 ·​·​{
150 ·​·​·​·​std:​:​cerr·​<<·​"Exception:​·​"·​<<·​e.​what()​·​<<·​"\n";​151 ·​·​·​·​std:​:​cerr·​<<·​"Exception:​·​"·​<<·​e.​what()​·​<<·​"\n";​
151 ·​·​}152 ·​·​}
152 153
153 ·​·​return·​0;​154 ·​·​return·​0;​
154 }155 }