2 // Copyright (c) 2003-2017 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 boost::asio::io_service
29 \until boost::asio::io_service
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 query object and turns it into a list of endpoints. We
38 construct a query using the name of the server, specified in <tt>argv[1]</tt>,
39 and the name of the service, in this case <tt>"daytime"</tt>.
41 \until tcp::resolver::query
43 The list of endpoints is returned using an iterator of type
44 boost::asio::ip::tcp::resolver::iterator. (Note that a default constructed
45 boost::asio::ip::tcp::resolver::iterator object can be used as an end iterator.)
47 \until tcp::resolver::iterator
49 Now we create and connect the socket. The list of endpoints obtained above may
50 contain both IPv4 and IPv6 endpoints, so we need to try each of them until we
51 find one that works. This keeps the client program independent of a specific IP
52 version. The boost::asio::connect() function does this for us automatically.
54 \until boost::asio::connect
56 The connection is open. All we need to do now is read the response from the
59 We use a <tt>boost::array</tt> to hold the received data. The boost::asio::buffer()
60 function automatically determines the size of the array to help prevent buffer
61 overruns. Instead of a <tt>boost::array</tt>, we could have used a <tt>char
62 []</tt> or <tt>std::vector</tt>.
66 When the server closes the connection, the boost::asio::ip::tcp::socket::read_some()
67 function will exit with the boost::asio::error::eof error, which is how we know to
72 Finally, handle any exceptions that may have been thrown.
77 See the \ref tutdaytime1src "full source listing" \n
78 Return to the \ref index "tutorial index" \n
79 Next: \ref tutdaytime2
84 \page tutdaytime1src Source listing for Daytime.1
85 \include daytime1/client.cpp
86 Return to \ref tutdaytime1
90 \page tutdaytime2 Daytime.2 - A synchronous TCP daytime server
92 This tutorial program shows how to use asio to implement a server application
95 \dontinclude daytime2/server.cpp
100 We define the function <tt>make_daytime_string()</tt> to create the string to
101 be sent back to the client. This function will be reused in all of our daytime
104 \until boost::asio::io_service
106 A boost::asio::ip::tcp::acceptor object needs to be created to listen
107 for new connections. It is initialised to listen on TCP port 13, for IP version 4.
111 This is an iterative server, which means that it will handle one
112 connection at a time. Create a socket that will represent the connection to the
113 client, and then wait for a connection.
115 \until acceptor.accept
117 A client is accessing our service. Determine the current time
118 and transfer this information to the client.
123 Finally, handle any exceptions.
128 See the \ref tutdaytime2src "full source listing" \n
129 Return to the \ref index "tutorial index" \n
130 Previous: \ref tutdaytime1 \n
131 Next: \ref tutdaytime3
136 \page tutdaytime2src Source listing for Daytime.2
137 \include daytime2/server.cpp
138 Return to \ref tutdaytime2
142 \page tutdaytime3 Daytime.3 - An asynchronous TCP daytime server
144 \section tutdaytime3funcmain The main() function
146 \dontinclude daytime3/server.cpp
151 We need to create a server object to accept incoming client connections. The
152 boost::asio::io_service object provides I/O services, such as sockets, that the
153 server object will use.
157 Run the boost::asio::io_service object so that it will perform asynchronous operations
163 \section tutdaytime3classtcp_server The tcp_server class
165 \dontinclude daytime3/server.cpp
166 \skip class tcp_server
169 The constructor initialises an acceptor to listen on TCP port 13.
173 The function <tt>start_accept()</tt> creates a socket and initiates an
174 asynchronous accept operation to wait for a new connection.
178 The function <tt>handle_accept()</tt> is called when the asynchronous accept
179 operation initiated by <tt>start_accept()</tt> finishes. It services the client
180 request, and then calls <tt>start_accept()</tt> to initiate the next accept
186 \section tutdaytime3classtcp_connection The tcp_connection class
188 We will use <tt>shared_ptr</tt> and <tt>enable_shared_from_this</tt> because we
189 want to keep the <tt>tcp_connection</tt> object alive as long as there is an
190 operation that refers to it.
192 \dontinclude daytime3/server.cpp
193 \skip class tcp_connection
198 In the function <tt>start()</tt>, we call boost::asio::async_write() to serve the data
199 to the client. Note that we are using boost::asio::async_write(), rather than
200 boost::asio::ip::tcp::socket::async_write_some(), to ensure that the entire block of
205 The data to be sent is stored in the class member <tt>message_</tt> as we need
206 to keep the data valid until the asynchronous operation is complete.
210 When initiating the asynchronous operation, and if using boost::bind(), you
211 must specify only the arguments that match the handler's parameter list. In
212 this program, both of the argument placeholders (boost::asio::placeholders::error and
213 boost::asio::placeholders::bytes_transferred) could potentially have been removed,
214 since they are not being used in <tt>handle_write()</tt>.
216 \until placeholders::bytes_transferred
218 Any further actions for this client connection are now the responsibility of
219 <tt>handle_write()</tt>.
223 \section tutdaytime3remunused Removing unused handler parameters
225 You may have noticed that the <tt>error</tt>, and <tt>bytes_transferred</tt>
226 parameters are not used in the body of the <tt>handle_write()</tt> function. If
227 parameters are not needed, it is possible to remove them from the function so
236 The boost::asio::async_write() call used to initiate the call can then be changed to
240 boost::asio::async_write(socket_, boost::asio::buffer(message_),
241 boost::bind(&tcp_connection::handle_write, shared_from_this()));
244 See the \ref tutdaytime3src "full source listing" \n
245 Return to the \ref index "tutorial index" \n
246 Previous: \ref tutdaytime2 \n
247 Next: \ref tutdaytime4
252 \page tutdaytime3src Source listing for Daytime.3
253 \include daytime3/server.cpp
254 Return to \ref tutdaytime3
258 \page tutdaytime4 Daytime.4 - A synchronous UDP daytime client
260 This tutorial program shows how to use asio to implement a client application
263 \dontinclude daytime4/client.cpp
265 \until using boost::asio::ip::udp;
267 The start of the application is essentially the same as for the TCP daytime
270 \until boost::asio::io_service
272 We use an boost::asio::ip::udp::resolver object to find the correct remote endpoint to
273 use based on the host and service names. The query is restricted to return only
274 IPv4 endpoints by the boost::asio::ip::udp::v4() argument.
278 The boost::asio::ip::udp::resolver::resolve() function is guaranteed to return at
279 least one endpoint in the list if it does not fail. This means it is safe to
280 dereference the return value directly.
284 Since UDP is datagram-oriented, we will not be using a stream socket. Create an
285 boost::asio::ip::udp::socket and initiate contact with the remote endpoint.
287 \until receiver_endpoint
289 Now we need to be ready to accept whatever the server sends back to us. The
290 endpoint on our side that receives the server's response will be initialised by
291 boost::asio::ip::udp::socket::receive_from().
295 Finally, handle any exceptions that may have been thrown.
299 See the \ref tutdaytime4src "full source listing" \n
300 Return to the \ref index "tutorial index" \n
301 Previous: \ref tutdaytime3 \n
302 Next: \ref tutdaytime5
307 \page tutdaytime4src Source listing for Daytime.4
308 \include daytime4/client.cpp
309 Return to \ref tutdaytime4
313 \page tutdaytime5 Daytime.5 - A synchronous UDP daytime server
315 This tutorial program shows how to use asio to implement a server application
318 \dontinclude daytime5/server.cpp
320 \until boost::asio::io_service
322 Create an boost::asio::ip::udp::socket object to receive requests on UDP port 13.
326 Wait for a client to initiate contact with us. The remote_endpoint object will
327 be populated by boost::asio::ip::udp::socket::receive_from().
331 Determine what we are going to send back to the client.
333 \until std::string message
335 Send the response to the remote_endpoint.
340 Finally, handle any exceptions.
345 See the \ref tutdaytime5src "full source listing" \n
346 Return to the \ref index "tutorial index" \n
347 Previous: \ref tutdaytime4 \n
348 Next: \ref tutdaytime6
353 \page tutdaytime5src Source listing for Daytime.5
354 \include daytime5/server.cpp
355 Return to \ref tutdaytime5
359 \page tutdaytime6 Daytime.6 - An asynchronous UDP daytime server
361 \section tutdaytime6funcmain The main() function
363 \dontinclude daytime6/server.cpp
368 Create a server object to accept incoming client requests, and run
369 the boost::asio::io_service object.
374 \section tutdaytime6classudp_server The udp_server class
376 \dontinclude daytime6/server.cpp
377 \skip class udp_server
380 The constructor initialises a socket to listen on UDP port 13.
385 The function boost::asio::ip::udp::socket::async_receive_from() will cause the
386 application to listen in the background for a new request. When such a request
387 is received, the boost::asio::io_service object will invoke the
388 <tt>handle_receive()</tt> function with two arguments: a value of type
389 boost::system::error_code indicating whether the operation succeeded or failed, and a
390 <tt>size_t</tt> value <tt>bytes_transferred</tt> specifying the number of bytes
395 The function <tt>handle_receive()</tt> will service the client request.
399 The <tt>error</tt> parameter contains the result of the asynchronous operation.
400 Since we only provide the 1-byte <tt>recv_buffer_</tt> to contain the client's
401 request, the boost::asio::io_service object would return an error if the client sent
402 anything larger. We can ignore such an error if it comes up.
406 Determine what we are going to send.
408 \until make_daytime_string()
410 We now call boost::asio::ip::udp::socket::async_send_to() to serve the data to the
413 \until boost::asio::placeholders::bytes_transferred
415 When initiating the asynchronous operation, and if using boost::bind(), you
416 must specify only the arguments that match the handler's parameter list. In
417 this program, both of the argument placeholders (boost::asio::placeholders::error and
418 boost::asio::placeholders::bytes_transferred) could potentially have been removed.
420 Start listening for the next client request.
424 Any further actions for this client request are now the responsibility of
425 <tt>handle_send()</tt>.
430 The function <tt>handle_send()</tt> is invoked after the service request has
436 See the \ref tutdaytime6src "full source listing" \n
437 Return to the \ref index "tutorial index" \n
438 Previous: \ref tutdaytime5 \n
439 Next: \ref tutdaytime7
444 \page tutdaytime6src Source listing for Daytime.6
445 \include daytime6/server.cpp
446 Return to \ref tutdaytime6
450 \page tutdaytime7 Daytime.7 - A combined TCP/UDP asynchronous server
452 This tutorial program shows how to combine the two asynchronous servers that we
453 have just written, into a single server application.
455 \section tutdaytime7funcmain The main() function
457 \dontinclude daytime7/server.cpp
459 \until boost::asio::io_service
461 We will begin by creating a server object to accept a TCP client connection.
465 We also need a server object to accept a UDP client request.
469 We have created two lots of work for the boost::asio::io_service object to do.
474 \section tutdaytime7classtcp The tcp_connection and tcp_server classes
476 The following two classes are taken from \ref tutdaytime3 "Daytime.3".
478 \dontinclude daytime7/server.cpp
479 \skip class tcp_connection
483 \section tutdaytime7classudp The udp_server class
485 Similarly, this next class is taken from the
486 \ref tutdaytime6 "previous tutorial step".
488 \dontinclude daytime7/server.cpp
489 \skip class udp_server
492 See the \ref tutdaytime7src "full source listing" \n
493 Return to the \ref index "tutorial index" \n
494 Previous: \ref tutdaytime6
499 \page tutdaytime7src Source listing for Daytime.7
500 \include daytime7/server.cpp
501 Return to \ref tutdaytime7