tutdaytime6.html
7.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Daytime.6 - An asynchronous UDP daytime server</title>
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Asio">
<link rel="up" href="../tutorial.html" title="Tutorial">
<link rel="prev" href="tutdaytime5/src.html" title="Source listing for Daytime.5">
<link rel="next" href="tutdaytime6/src.html" title="Source listing for Daytime.6">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="asio C++ library" width="250" height="60" src="../../asio.png"></td></tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tutdaytime5/src.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="tutdaytime6/src.html"><img src="../../next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="asio.tutorial.tutdaytime6"></a><a class="link" href="tutdaytime6.html" title="Daytime.6 - An asynchronous UDP daytime server">Daytime.6 - An asynchronous
UDP daytime server</a>
</h3></div></div></div>
<h5>
<a name="asio.tutorial.tutdaytime6.h0"></a>
<span><a name="asio.tutorial.tutdaytime6.the_main___function"></a></span><a class="link" href="tutdaytime6.html#asio.tutorial.tutdaytime6.the_main___function">The
main() function</a>
</h5>
<pre class="programlisting">int main()
{
try
{
</pre>
<p>
Create a server object to accept incoming client requests, and run the <a class="link" href="../reference/io_context.html" title="io_context">io_context</a> object.
</p>
<pre class="programlisting"> asio::io_context io_context;
udp_server server(io_context);
io_context.run();
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
return 0;
}
</pre>
<h5>
<a name="asio.tutorial.tutdaytime6.h1"></a>
<span><a name="asio.tutorial.tutdaytime6.the_udp_server_class"></a></span><a class="link" href="tutdaytime6.html#asio.tutorial.tutdaytime6.the_udp_server_class">The
udp_server class</a>
</h5>
<pre class="programlisting">class udp_server
{
public:
</pre>
<p>
The constructor initialises a socket to listen on UDP port 13.
</p>
<pre class="programlisting"> udp_server(asio::io_context& io_context)
: socket_(io_context, udp::endpoint(udp::v4(), 13))
{
start_receive();
}
private:
void start_receive()
{
</pre>
<p>
The function <a class="link" href="../reference/basic_datagram_socket/async_receive_from.html" title="basic_datagram_socket::async_receive_from">ip::udp::socket::async_receive_from()</a>
will cause the application to listen in the background for a new request.
When such a request is received, the <a class="link" href="../reference/io_context.html" title="io_context">io_context</a>
object will invoke the <code class="computeroutput">handle_receive()</code> function with two arguments:
a value of type <a class="link" href="../reference/error_code.html" title="error_code">error_code</a>
indicating whether the operation succeeded or failed, and a <code class="computeroutput">size_t</code>
value <code class="computeroutput">bytes_transferred</code> specifying the number of bytes received.
</p>
<pre class="programlisting"> socket_.async_receive_from(
asio::buffer(recv_buffer_), remote_endpoint_,
boost::bind(&udp_server::handle_receive, this,
asio::placeholders::error,
asio::placeholders::bytes_transferred));
}
</pre>
<p>
The function <code class="computeroutput">handle_receive()</code> will service the client request.
</p>
<pre class="programlisting"> void handle_receive(const asio::error_code& error,
std::size_t /*bytes_transferred*/)
{
</pre>
<p>
The <code class="computeroutput">error</code> parameter contains the result of the asynchronous
operation. Since we only provide the 1-byte <code class="computeroutput">recv_buffer_</code> to
contain the client's request, the <a class="link" href="../reference/io_context.html" title="io_context">io_context</a>
object would return an error if the client sent anything larger. We can ignore
such an error if it comes up.
</p>
<pre class="programlisting"> if (!error)
{
</pre>
<p>
Determine what we are going to send.
</p>
<pre class="programlisting"> boost::shared_ptr<std::string> message(
new std::string(make_daytime_string()));
</pre>
<p>
We now call <a class="link" href="../reference/basic_datagram_socket/async_send_to.html" title="basic_datagram_socket::async_send_to">ip::udp::socket::async_send_to()</a>
to serve the data to the client.
</p>
<pre class="programlisting"> socket_.async_send_to(asio::buffer(*message), remote_endpoint_,
boost::bind(&udp_server::handle_send, this, message,
asio::placeholders::error,
asio::placeholders::bytes_transferred));
</pre>
<p>
When initiating the asynchronous operation, and if using <a class="link" href="boost_bind.html" title="boost::bind">boost::bind</a>
, you must specify only the arguments that match the handler's parameter
list. In this program, both of the argument placeholders (asio::placeholders::error
and asio::placeholders::bytes_transferred) could potentially have been removed.
</p>
<p>
Start listening for the next client request.
</p>
<pre class="programlisting"> start_receive();
</pre>
<p>
Any further actions for this client request are now the responsibility of
<code class="computeroutput">handle_send()</code>.
</p>
<pre class="programlisting"> }
}
</pre>
<p>
The function <code class="computeroutput">handle_send()</code> is invoked after the service request
has been completed.
</p>
<pre class="programlisting"> void handle_send(boost::shared_ptr<std::string> /*message*/,
const asio::error_code& /*error*/,
std::size_t /*bytes_transferred*/)
{
}
udp::socket socket_;
udp::endpoint remote_endpoint_;
boost::array<char, 1> recv_buffer_;
};
</pre>
<p>
See the <a class="link" href="tutdaytime6/src.html" title="Source listing for Daytime.6">full source listing</a>
</p>
<p>
Return to the <a class="link" href="../tutorial.html" title="Tutorial">tutorial index</a>
</p>
<p>
Previous: <a class="link" href="tutdaytime5.html" title="Daytime.5 - A synchronous UDP daytime server">Daytime.5 - A synchronous
UDP daytime server</a>
</p>
<p>
Next: <a class="link" href="tutdaytime7.html" title="Daytime.7 - A combined TCP/UDP asynchronous server">Daytime.7 - A combined TCP/UDP
asynchronous server</a>
</p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2003-2020 Christopher M.
Kohlhoff<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tutdaytime5/src.html"><img src="../../prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../home.png" alt="Home"></a><a accesskey="n" href="tutdaytime6/src.html"><img src="../../next.png" alt="Next"></a>
</div>
</body>
</html>