2 // Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 \page tutdaytime1 Daytime.1 - A synchronous TCP daytime client
11 This tutorial program shows how to use asio to implement a client application
14 \dontinclude daytime1/client.cpp
17 We start by including the necessary header files.
21 The purpose of this application is to access a daytime service,
22 so we need the user to specify the server.
26 All programs that use asio need to have at least one I/O execution context,
27 such as an boost::asio::io_context object.
29 \until boost::asio::io_context
31 We need to turn the server name that was specified as a parameter to the
32 application, into a TCP endpoint. To do this we use an
33 boost::asio::ip::tcp::resolver object.
37 A resolver takes a host name and service name and turns them into a list of
38 endpoints. We perform a resolve call using the name of the server, specified in
39 <tt>argv[1]</tt>, and the name of the service, in this case <tt>"daytime"</tt>.
41 The list of endpoints is returned using an object of type
42 boost::asio::ip::tcp::resolver::results_type. This object is a range, with begin() and
43 end() member functions that may be used for iterating over the results.
45 \until resolver.resolve
47 Now we create and connect the socket. The list of endpoints obtained above may
48 contain both IPv4 and IPv6 endpoints, so we need to try each of them until we
49 find one that works. This keeps the client program independent of a specific IP
50 version. The boost::asio::connect() function does this for us automatically.
52 \until boost::asio::connect
54 The connection is open. All we need to do now is read the response from the
57 We use a <tt>boost::array</tt> to hold the received data. The boost::asio::buffer()
58 function automatically determines the size of the array to help prevent buffer
59 overruns. Instead of a <tt>boost::array</tt>, we could have used a <tt>char
60 []</tt> or <tt>std::vector</tt>.
64 When the server closes the connection, the boost::asio::ip::tcp::socket::read_some()
65 function will exit with the boost::asio::error::eof error, which is how we know to
70 Finally, handle any exceptions that may have been thrown.
75 See the \ref tutdaytime1src "full source listing" \n
76 Return to the \ref index "tutorial index" \n
77 Next: \ref tutdaytime2
82 \page tutdaytime1src Source listing for Daytime.1
83 \include daytime1/client.cpp
84 Return to \ref tutdaytime1
88 \page tutdaytime2 Daytime.2 - A synchronous TCP daytime server
90 This tutorial program shows how to use asio to implement a server application
93 \dontinclude daytime2/server.cpp
98 We define the function <tt>make_daytime_string()</tt> to create the string to
99 be sent back to the client. This function will be reused in all of our daytime
102 \until boost::asio::io_context
104 A boost::asio::ip::tcp::acceptor object needs to be created to listen
105 for new connections. It is initialised to listen on TCP port 13, for IP version 4.
109 This is an iterative server, which means that it will handle one
110 connection at a time. Create a socket that will represent the connection to the
111 client, and then wait for a connection.
113 \until acceptor.accept
115 A client is accessing our service. Determine the current time
116 and transfer this information to the client.
121 Finally, handle any exceptions.
126 See the \ref tutdaytime2src "full source listing" \n
127 Return to the \ref index "tutorial index" \n
128 Previous: \ref tutdaytime1 \n
129 Next: \ref tutdaytime3
134 \page tutdaytime2src Source listing for Daytime.2
135 \include daytime2/server.cpp
136 Return to \ref tutdaytime2
140 \page tutdaytime3 Daytime.3 - An asynchronous TCP daytime server
142 \section tutdaytime3funcmain The main() function
144 \dontinclude daytime3/server.cpp
149 We need to create a server object to accept incoming client connections. The
150 boost::asio::io_context object provides I/O services, such as sockets, that the
151 server object will use.
155 Run the boost::asio::io_context object so that it will perform asynchronous operations
161 \section tutdaytime3classtcp_server The tcp_server class
163 \dontinclude daytime3/server.cpp
164 \skip class tcp_server
167 The constructor initialises an acceptor to listen on TCP port 13.
171 The function <tt>start_accept()</tt> creates a socket and initiates an
172 asynchronous accept operation to wait for a new connection.
176 The function <tt>handle_accept()</tt> is called when the asynchronous accept
177 operation initiated by <tt>start_accept()</tt> finishes. It services the client
178 request, and then calls <tt>start_accept()</tt> to initiate the next accept
184 \section tutdaytime3classtcp_connection The tcp_connection class
186 We will use <tt>shared_ptr</tt> and <tt>enable_shared_from_this</tt> because we
187 want to keep the <tt>tcp_connection</tt> object alive as long as there is an
188 operation that refers to it.
190 \dontinclude daytime3/server.cpp
191 \skip class tcp_connection
196 In the function <tt>start()</tt>, we call boost::asio::async_write() to serve the data
197 to the client. Note that we are using boost::asio::async_write(), rather than
198 boost::asio::ip::tcp::socket::async_write_some(), to ensure that the entire block of
203 The data to be sent is stored in the class member <tt>message_</tt> as we need
204 to keep the data valid until the asynchronous operation is complete.
208 When initiating the asynchronous operation, and if using boost::bind(), you
209 must specify only the arguments that match the handler's parameter list. In
210 this program, both of the argument placeholders (boost::asio::placeholders::error and
211 boost::asio::placeholders::bytes_transferred) could potentially have been removed,
212 since they are not being used in <tt>handle_write()</tt>.
214 \until placeholders::bytes_transferred
216 Any further actions for this client connection are now the responsibility of
217 <tt>handle_write()</tt>.
221 \section tutdaytime3remunused Removing unused handler parameters
223 You may have noticed that the <tt>error</tt>, and <tt>bytes_transferred</tt>
224 parameters are not used in the body of the <tt>handle_write()</tt> function. If
225 parameters are not needed, it is possible to remove them from the function so
234 The boost::asio::async_write() call used to initiate the call can then be changed to
238 boost::asio::async_write(socket_, boost::asio::buffer(message_),
239 boost::bind(&tcp_connection::handle_write, shared_from_this()));
242 See the \ref tutdaytime3src "full source listing" \n
243 Return to the \ref index "tutorial index" \n
244 Previous: \ref tutdaytime2 \n
245 Next: \ref tutdaytime4
250 \page tutdaytime3src Source listing for Daytime.3
251 \include daytime3/server.cpp
252 Return to \ref tutdaytime3
256 \page tutdaytime4 Daytime.4 - A synchronous UDP daytime client
258 This tutorial program shows how to use asio to implement a client application
261 \dontinclude daytime4/client.cpp
263 \until using boost::asio::ip::udp;
265 The start of the application is essentially the same as for the TCP daytime
268 \until boost::asio::io_context
270 We use an boost::asio::ip::udp::resolver object to find the correct remote endpoint to
271 use based on the host and service names. The query is restricted to return only
272 IPv4 endpoints by the boost::asio::ip::udp::v4() argument.
276 The boost::asio::ip::udp::resolver::resolve() function is guaranteed to return at
277 least one endpoint in the list if it does not fail. This means it is safe to
278 dereference the return value directly.
280 Since UDP is datagram-oriented, we will not be using a stream socket. Create an
281 boost::asio::ip::udp::socket and initiate contact with the remote endpoint.
283 \until receiver_endpoint
285 Now we need to be ready to accept whatever the server sends back to us. The
286 endpoint on our side that receives the server's response will be initialised by
287 boost::asio::ip::udp::socket::receive_from().
291 Finally, handle any exceptions that may have been thrown.
295 See the \ref tutdaytime4src "full source listing" \n
296 Return to the \ref index "tutorial index" \n
297 Previous: \ref tutdaytime3 \n
298 Next: \ref tutdaytime5
303 \page tutdaytime4src Source listing for Daytime.4
304 \include daytime4/client.cpp
305 Return to \ref tutdaytime4
309 \page tutdaytime5 Daytime.5 - A synchronous UDP daytime server
311 This tutorial program shows how to use asio to implement a server application
314 \dontinclude daytime5/server.cpp
316 \until boost::asio::io_context
318 Create an boost::asio::ip::udp::socket object to receive requests on UDP port 13.
322 Wait for a client to initiate contact with us. The remote_endpoint object will
323 be populated by boost::asio::ip::udp::socket::receive_from().
327 Determine what we are going to send back to the client.
329 \until std::string message
331 Send the response to the remote_endpoint.
336 Finally, handle any exceptions.
341 See the \ref tutdaytime5src "full source listing" \n
342 Return to the \ref index "tutorial index" \n
343 Previous: \ref tutdaytime4 \n
344 Next: \ref tutdaytime6
349 \page tutdaytime5src Source listing for Daytime.5
350 \include daytime5/server.cpp
351 Return to \ref tutdaytime5
355 \page tutdaytime6 Daytime.6 - An asynchronous UDP daytime server
357 \section tutdaytime6funcmain The main() function
359 \dontinclude daytime6/server.cpp
364 Create a server object to accept incoming client requests, and run
365 the boost::asio::io_context object.
370 \section tutdaytime6classudp_server The udp_server class
372 \dontinclude daytime6/server.cpp
373 \skip class udp_server
376 The constructor initialises a socket to listen on UDP port 13.
381 The function boost::asio::ip::udp::socket::async_receive_from() will cause the
382 application to listen in the background for a new request. When such a request
383 is received, the boost::asio::io_context object will invoke the
384 <tt>handle_receive()</tt> function with two arguments: a value of type
385 boost::system::error_code indicating whether the operation succeeded or failed, and a
386 <tt>size_t</tt> value <tt>bytes_transferred</tt> specifying the number of bytes
391 The function <tt>handle_receive()</tt> will service the client request.
395 The <tt>error</tt> parameter contains the result of the asynchronous operation.
396 Since we only provide the 1-byte <tt>recv_buffer_</tt> to contain the client's
397 request, the boost::asio::io_context object would return an error if the client sent
398 anything larger. We can ignore such an error if it comes up.
402 Determine what we are going to send.
404 \until make_daytime_string()
406 We now call boost::asio::ip::udp::socket::async_send_to() to serve the data to the
409 \until boost::asio::placeholders::bytes_transferred
411 When initiating the asynchronous operation, and if using boost::bind(), you
412 must specify only the arguments that match the handler's parameter list. In
413 this program, both of the argument placeholders (boost::asio::placeholders::error and
414 boost::asio::placeholders::bytes_transferred) could potentially have been removed.
416 Start listening for the next client request.
420 Any further actions for this client request are now the responsibility of
421 <tt>handle_send()</tt>.
426 The function <tt>handle_send()</tt> is invoked after the service request has
432 See the \ref tutdaytime6src "full source listing" \n
433 Return to the \ref index "tutorial index" \n
434 Previous: \ref tutdaytime5 \n
435 Next: \ref tutdaytime7
440 \page tutdaytime6src Source listing for Daytime.6
441 \include daytime6/server.cpp
442 Return to \ref tutdaytime6
446 \page tutdaytime7 Daytime.7 - A combined TCP/UDP asynchronous server
448 This tutorial program shows how to combine the two asynchronous servers that we
449 have just written, into a single server application.
451 \section tutdaytime7funcmain The main() function
453 \dontinclude daytime7/server.cpp
455 \until boost::asio::io_context
457 We will begin by creating a server object to accept a TCP client connection.
461 We also need a server object to accept a UDP client request.
465 We have created two lots of work for the boost::asio::io_context object to do.
470 \section tutdaytime7classtcp The tcp_connection and tcp_server classes
472 The following two classes are taken from \ref tutdaytime3 "Daytime.3".
474 \dontinclude daytime7/server.cpp
475 \skip class tcp_connection
479 \section tutdaytime7classudp The udp_server class
481 Similarly, this next class is taken from the
482 \ref tutdaytime6 "previous tutorial step".
484 \dontinclude daytime7/server.cpp
485 \skip class udp_server
488 See the \ref tutdaytime7src "full source listing" \n
489 Return to the \ref index "tutorial index" \n
490 Previous: \ref tutdaytime6
495 \page tutdaytime7src Source listing for Daytime.7
496 \include daytime7/server.cpp
497 Return to \ref tutdaytime7