[DEV] add v1.76.0

This commit is contained in:
2021-10-05 21:37:46 +02:00
parent a97e9ae7d4
commit d0115b733d
45133 changed files with 4744437 additions and 1026325 deletions

View File

@@ -0,0 +1,158 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Daytime.1 - A synchronous TCP daytime client</title>
<link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../boost_asio.html" title="Boost.Asio">
<link rel="up" href="../tutorial.html" title="Tutorial">
<link rel="prev" href="tuttimer5/src.html" title="Source listing for Timer.5">
<link rel="next" href="tutdaytime1/src.html" title="Source listing for Daytime.1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../boost.png"></td>
<td align="center"><a href="../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tuttimer5/src.html"><img src="../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../boost_asio.html"><img src="../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tutdaytime1/src.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_asio.tutorial.tutdaytime1"></a><a class="link" href="tutdaytime1.html" title="Daytime.1 - A synchronous TCP daytime client">Daytime.1 - A synchronous
TCP daytime client</a>
</h3></div></div></div>
<p>
This tutorial program shows how to use asio to implement a client application
with TCP.
</p>
<p>
We start by including the necessary header files.
</p>
<pre class="programlisting">#include &lt;iostream&gt;
#include &lt;boost/array.hpp&gt;
#include &lt;boost/asio.hpp&gt;
</pre>
<p>
The purpose of this application is to access a daytime service, so we need
the user to specify the server.
</p>
<pre class="programlisting">using boost::asio::ip::tcp;
int main(int argc, char* argv[])
{
try
{
if (argc != 2)
{
std::cerr &lt;&lt; "Usage: client &lt;host&gt;" &lt;&lt; std::endl;
return 1;
}
</pre>
<p>
All programs that use asio need to have at least one I/O execution context,
such as an <a class="link" href="../reference/io_context.html" title="io_context">io_context</a>
object.
</p>
<pre class="programlisting"> boost::asio::io_context io_context;
</pre>
<p>
We need to turn the server name that was specified as a parameter to the
application, into a TCP endpoint. To do this we use an <a class="link" href="../reference/ip__tcp/resolver.html" title="ip::tcp::resolver">ip::tcp::resolver</a>
object.
</p>
<pre class="programlisting"> tcp::resolver resolver(io_context);
</pre>
<p>
A resolver takes a host name and service name and turns them into a list
of endpoints. We perform a resolve call using the name of the server, specified
in <code class="computeroutput">argv[1]</code>, and the name of the service, in this case <code class="computeroutput">"daytime"</code>.
</p>
<p>
The list of endpoints is returned using an object of type <a class="link" href="../reference/ip__basic_resolver/results_type.html" title="ip::basic_resolver::results_type">ip::tcp::resolver::results_type</a>.
This object is a range, with begin() and end() member functions that may
be used for iterating over the results.
</p>
<pre class="programlisting"> tcp::resolver::results_type endpoints =
resolver.resolve(argv[1], "daytime");
</pre>
<p>
Now we create and connect the socket. The list of endpoints obtained above
may contain both IPv4 and IPv6 endpoints, so we need to try each of them
until we find one that works. This keeps the client program independent of
a specific IP version. The boost::asio::connect() function does this for
us automatically.
</p>
<pre class="programlisting"> tcp::socket socket(io_context);
boost::asio::connect(socket, endpoints);
</pre>
<p>
The connection is open. All we need to do now is read the response from the
daytime service.
</p>
<p>
We use a <code class="computeroutput">boost::array</code> to hold the received data. The boost::asio::buffer()
function automatically determines the size of the array to help prevent buffer
overruns. Instead of a <code class="computeroutput">boost::array</code>, we could have used a <code class="computeroutput">char
[]</code> or <code class="computeroutput">std::vector</code>.
</p>
<pre class="programlisting"> for (;;)
{
boost::array&lt;char, 128&gt; buf;
boost::system::error_code error;
size_t len = socket.read_some(boost::asio::buffer(buf), error);
</pre>
<p>
When the server closes the connection, the <a class="link" href="../reference/basic_stream_socket/read_some.html" title="basic_stream_socket::read_some">ip::tcp::socket::read_some()</a>
function will exit with the boost::asio::error::eof error, which is how we
know to exit the loop.
</p>
<pre class="programlisting"> if (error == boost::asio::error::eof)
break; // Connection closed cleanly by peer.
else if (error)
throw boost::system::system_error(error); // Some other error.
std::cout.write(buf.data(), len);
}
</pre>
<p>
Finally, handle any exceptions that may have been thrown.
</p>
<pre class="programlisting"> }
catch (std::exception&amp; e)
{
std::cerr &lt;&lt; e.what() &lt;&lt; std::endl;
}
</pre>
<p>
See the <a class="link" href="tutdaytime1/src.html" title="Source listing for Daytime.1">full source listing</a>
</p>
<p>
Return to the <a class="link" href="../tutorial.html" title="Tutorial">tutorial index</a>
</p>
<p>
Next: <a class="link" href="tutdaytime2.html" title="Daytime.2 - A synchronous TCP daytime server">Daytime.2 - A synchronous
TCP daytime 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-2021 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="tuttimer5/src.html"><img src="../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../boost_asio.html"><img src="../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tutdaytime1/src.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,107 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Source listing for Daytime.1</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../../boost_asio.html" title="Boost.Asio">
<link rel="up" href="../tutdaytime1.html" title="Daytime.1 - A synchronous TCP daytime client">
<link rel="prev" href="../tutdaytime1.html" title="Daytime.1 - A synchronous TCP daytime client">
<link rel="next" href="../tutdaytime2.html" title="Daytime.2 - A synchronous TCP daytime server">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../tutdaytime1.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutdaytime1.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../tutdaytime2.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_asio.tutorial.tutdaytime1.src"></a><a class="link" href="src.html" title="Source listing for Daytime.1">Source listing
for Daytime.1</a>
</h4></div></div></div>
<pre class="programlisting">//
// client.cpp
// ~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include &lt;iostream&gt;
#include &lt;boost/array.hpp&gt;
#include &lt;boost/asio.hpp&gt;
using boost::asio::ip::tcp;
int main(int argc, char* argv[])
{
try
{
if (argc != 2)
{
std::cerr &lt;&lt; "Usage: client &lt;host&gt;" &lt;&lt; std::endl;
return 1;
}
boost::asio::io_context io_context;
tcp::resolver resolver(io_context);
tcp::resolver::results_type endpoints =
resolver.resolve(argv[1], "daytime");
tcp::socket socket(io_context);
boost::asio::connect(socket, endpoints);
for (;;)
{
boost::array&lt;char, 128&gt; buf;
boost::system::error_code error;
size_t len = socket.read_some(boost::asio::buffer(buf), error);
if (error == boost::asio::error::eof)
break; // Connection closed cleanly by peer.
else if (error)
throw boost::system::system_error(error); // Some other error.
std::cout.write(buf.data(), len);
}
}
catch (std::exception&amp; e)
{
std::cerr &lt;&lt; e.what() &lt;&lt; std::endl;
}
return 0;
}
</pre>
<p>
Return to <a class="link" href="../tutdaytime1.html" title="Daytime.1 - A synchronous TCP daytime client">Daytime.1 - A
synchronous TCP daytime client</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-2021 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="../tutdaytime1.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutdaytime1.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../tutdaytime2.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,127 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Daytime.2 - A synchronous TCP daytime server</title>
<link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../boost_asio.html" title="Boost.Asio">
<link rel="up" href="../tutorial.html" title="Tutorial">
<link rel="prev" href="tutdaytime1/src.html" title="Source listing for Daytime.1">
<link rel="next" href="tutdaytime2/src.html" title="Source listing for Daytime.2">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../boost.png"></td>
<td align="center"><a href="../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tutdaytime1/src.html"><img src="../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../boost_asio.html"><img src="../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tutdaytime2/src.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_asio.tutorial.tutdaytime2"></a><a class="link" href="tutdaytime2.html" title="Daytime.2 - A synchronous TCP daytime server">Daytime.2 - A synchronous
TCP daytime server</a>
</h3></div></div></div>
<p>
This tutorial program shows how to use asio to implement a server application
with TCP.
</p>
<pre class="programlisting">#include &lt;ctime&gt;
#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;boost/asio.hpp&gt;
using boost::asio::ip::tcp;
</pre>
<p>
We define the function <code class="computeroutput">make_daytime_string()</code> to create the string
to be sent back to the client. This function will be reused in all of our
daytime server applications.
</p>
<pre class="programlisting">std::string make_daytime_string()
{
using namespace std; // For time_t, time and ctime;
time_t now = time(0);
return ctime(&amp;now);
}
int main()
{
try
{
boost::asio::io_context io_context;
</pre>
<p>
A <a class="link" href="../reference/ip__tcp/acceptor.html" title="ip::tcp::acceptor">ip::tcp::acceptor</a>
object needs to be created to listen for new connections. It is initialised
to listen on TCP port 13, for IP version 4.
</p>
<pre class="programlisting"> tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v4(), 13));
</pre>
<p>
This is an iterative server, which means that it will handle one connection
at a time. Create a socket that will represent the connection to the client,
and then wait for a connection.
</p>
<pre class="programlisting"> for (;;)
{
tcp::socket socket(io_context);
acceptor.accept(socket);
</pre>
<p>
A client is accessing our service. Determine the current time and transfer
this information to the client.
</p>
<pre class="programlisting"> std::string message = make_daytime_string();
boost::system::error_code ignored_error;
boost::asio::write(socket, boost::asio::buffer(message), ignored_error);
}
}
</pre>
<p>
Finally, handle any exceptions.
</p>
<pre class="programlisting"> catch (std::exception&amp; e)
{
std::cerr &lt;&lt; e.what() &lt;&lt; std::endl;
}
return 0;
}
</pre>
<p>
See the <a class="link" href="tutdaytime2/src.html" title="Source listing for Daytime.2">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="tutdaytime1.html" title="Daytime.1 - A synchronous TCP daytime client">Daytime.1 - A synchronous
TCP daytime client</a>
</p>
<p>
Next: <a class="link" href="tutdaytime3.html" title="Daytime.3 - An asynchronous TCP daytime server">Daytime.3 - An asynchronous
TCP daytime 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-2021 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="tutdaytime1/src.html"><img src="../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../boost_asio.html"><img src="../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tutdaytime2/src.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,100 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Source listing for Daytime.2</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../../boost_asio.html" title="Boost.Asio">
<link rel="up" href="../tutdaytime2.html" title="Daytime.2 - A synchronous TCP daytime server">
<link rel="prev" href="../tutdaytime2.html" title="Daytime.2 - A synchronous TCP daytime server">
<link rel="next" href="../tutdaytime3.html" title="Daytime.3 - An asynchronous TCP daytime server">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../tutdaytime2.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutdaytime2.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../tutdaytime3.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_asio.tutorial.tutdaytime2.src"></a><a class="link" href="src.html" title="Source listing for Daytime.2">Source listing
for Daytime.2</a>
</h4></div></div></div>
<pre class="programlisting">//
// server.cpp
// ~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include &lt;ctime&gt;
#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;boost/asio.hpp&gt;
using boost::asio::ip::tcp;
std::string make_daytime_string()
{
using namespace std; // For time_t, time and ctime;
time_t now = time(0);
return ctime(&amp;now);
}
int main()
{
try
{
boost::asio::io_context io_context;
tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v4(), 13));
for (;;)
{
tcp::socket socket(io_context);
acceptor.accept(socket);
std::string message = make_daytime_string();
boost::system::error_code ignored_error;
boost::asio::write(socket, boost::asio::buffer(message), ignored_error);
}
}
catch (std::exception&amp; e)
{
std::cerr &lt;&lt; e.what() &lt;&lt; std::endl;
}
return 0;
}
</pre>
<p>
Return to <a class="link" href="../tutdaytime2.html" title="Daytime.2 - A synchronous TCP daytime server">Daytime.2 - A
synchronous TCP daytime 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-2021 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="../tutdaytime2.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutdaytime2.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../tutdaytime3.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,239 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Daytime.3 - An asynchronous TCP daytime server</title>
<link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../boost_asio.html" title="Boost.Asio">
<link rel="up" href="../tutorial.html" title="Tutorial">
<link rel="prev" href="tutdaytime2/src.html" title="Source listing for Daytime.2">
<link rel="next" href="tutdaytime3/src.html" title="Source listing for Daytime.3">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../boost.png"></td>
<td align="center"><a href="../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tutdaytime2/src.html"><img src="../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../boost_asio.html"><img src="../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tutdaytime3/src.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_asio.tutorial.tutdaytime3"></a><a class="link" href="tutdaytime3.html" title="Daytime.3 - An asynchronous TCP daytime server">Daytime.3 - An asynchronous
TCP daytime server</a>
</h3></div></div></div>
<h5>
<a name="boost_asio.tutorial.tutdaytime3.h0"></a>
<span class="phrase"><a name="boost_asio.tutorial.tutdaytime3.the_main___function"></a></span><a class="link" href="tutdaytime3.html#boost_asio.tutorial.tutdaytime3.the_main___function">The
main() function</a>
</h5>
<pre class="programlisting">int main()
{
try
{
</pre>
<p>
We need to create a server object to accept incoming client connections.
The <a class="link" href="../reference/io_context.html" title="io_context">io_context</a> object
provides I/O services, such as sockets, that the server object will use.
</p>
<pre class="programlisting"> boost::asio::io_context io_context;
tcp_server server(io_context);
</pre>
<p>
Run the <a class="link" href="../reference/io_context.html" title="io_context">io_context</a>
object so that it will perform asynchronous operations on your behalf.
</p>
<pre class="programlisting"> io_context.run();
}
catch (std::exception&amp; e)
{
std::cerr &lt;&lt; e.what() &lt;&lt; std::endl;
}
return 0;
}
</pre>
<h5>
<a name="boost_asio.tutorial.tutdaytime3.h1"></a>
<span class="phrase"><a name="boost_asio.tutorial.tutdaytime3.the_tcp_server_class"></a></span><a class="link" href="tutdaytime3.html#boost_asio.tutorial.tutdaytime3.the_tcp_server_class">The tcp_server
class</a>
</h5>
<pre class="programlisting">class tcp_server
{
public:
</pre>
<p>
The constructor initialises an acceptor to listen on TCP port 13.
</p>
<pre class="programlisting"> tcp_server(boost::asio::io_context&amp; io_context)
: io_context_(io_context),
acceptor_(io_context, tcp::endpoint(tcp::v4(), 13))
{
start_accept();
}
private:
</pre>
<p>
The function <code class="computeroutput">start_accept()</code> creates a socket and initiates an
asynchronous accept operation to wait for a new connection.
</p>
<pre class="programlisting"> void start_accept()
{
tcp_connection::pointer new_connection =
tcp_connection::create(io_context_);
acceptor_.async_accept(new_connection-&gt;socket(),
boost::bind(&amp;tcp_server::handle_accept, this, new_connection,
boost::asio::placeholders::error));
}
</pre>
<p>
The function <code class="computeroutput">handle_accept()</code> is called when the asynchronous
accept operation initiated by <code class="computeroutput">start_accept()</code> finishes. It services
the client request, and then calls <code class="computeroutput">start_accept()</code> to initiate
the next accept operation.
</p>
<pre class="programlisting"> void handle_accept(tcp_connection::pointer new_connection,
const boost::system::error_code&amp; error)
{
if (!error)
{
new_connection-&gt;start();
}
start_accept();
}
</pre>
<h5>
<a name="boost_asio.tutorial.tutdaytime3.h2"></a>
<span class="phrase"><a name="boost_asio.tutorial.tutdaytime3.the_tcp_connection_class"></a></span><a class="link" href="tutdaytime3.html#boost_asio.tutorial.tutdaytime3.the_tcp_connection_class">The tcp_connection
class</a>
</h5>
<p>
We will use <code class="computeroutput">shared_ptr</code> and <code class="computeroutput">enable_shared_from_this</code>
because we want to keep the <code class="computeroutput">tcp_connection</code> object alive as long
as there is an operation that refers to it.
</p>
<pre class="programlisting">class tcp_connection
: public boost::enable_shared_from_this&lt;tcp_connection&gt;
{
public:
typedef boost::shared_ptr&lt;tcp_connection&gt; pointer;
static pointer create(boost::asio::io_context&amp; io_context)
{
return pointer(new tcp_connection(io_context));
}
tcp::socket&amp; socket()
{
return socket_;
}
</pre>
<p>
In the function <code class="computeroutput">start()</code>, we call boost::asio::async_write()
to serve the data to the client. Note that we are using boost::asio::async_write(),
rather than <a class="link" href="../reference/basic_stream_socket/async_write_some.html" title="basic_stream_socket::async_write_some">ip::tcp::socket::async_write_some()</a>,
to ensure that the entire block of data is sent.
</p>
<pre class="programlisting"> void start()
{
</pre>
<p>
The data to be sent is stored in the class member <code class="computeroutput">message_</code> as
we need to keep the data valid until the asynchronous operation is complete.
</p>
<pre class="programlisting"> message_ = make_daytime_string();
</pre>
<p>
When initiating the asynchronous operation, and if using boost::bind(), you
must specify only the arguments that match the handler's parameter list.
In this program, both of the argument placeholders (boost::asio::placeholders::error
and boost::asio::placeholders::bytes_transferred) could potentially have
been removed, since they are not being used in <code class="computeroutput">handle_write()</code>.
</p>
<pre class="programlisting"> boost::asio::async_write(socket_, boost::asio::buffer(message_),
boost::bind(&amp;tcp_connection::handle_write, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
</pre>
<p>
Any further actions for this client connection are now the responsibility
of <code class="computeroutput">handle_write()</code>.
</p>
<pre class="programlisting"> }
private:
tcp_connection(boost::asio::io_context&amp; io_context)
: socket_(io_context)
{
}
void handle_write(const boost::system::error_code&amp; /*error*/,
size_t /*bytes_transferred*/)
{
}
tcp::socket socket_;
std::string message_;
};
</pre>
<h5>
<a name="boost_asio.tutorial.tutdaytime3.h3"></a>
<span class="phrase"><a name="boost_asio.tutorial.tutdaytime3.removing_unused_handler_parameters"></a></span><a class="link" href="tutdaytime3.html#boost_asio.tutorial.tutdaytime3.removing_unused_handler_parameters">Removing
unused handler parameters</a>
</h5>
<p>
You may have noticed that the <code class="computeroutput">error</code>, and <code class="computeroutput">bytes_transferred</code>
parameters are not used in the body of the <code class="computeroutput">handle_write()</code> function.
If parameters are not needed, it is possible to remove them from the function
so that it looks like:
</p>
<pre class="programlisting"> void handle_write()
{
}
</pre>
<p>
The boost::asio::async_write() call used to initiate the call can then be
changed to just:
</p>
<pre class="programlisting"> boost::asio::async_write(socket_, boost::asio::buffer(message_),
boost::bind(&amp;tcp_connection::handle_write, shared_from_this()));
</pre>
<p>
See the <a class="link" href="tutdaytime3/src.html" title="Source listing for Daytime.3">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="tutdaytime2.html" title="Daytime.2 - A synchronous TCP daytime server">Daytime.2 - A synchronous
TCP daytime server</a>
</p>
<p>
Next: <a class="link" href="tutdaytime4.html" title="Daytime.4 - A synchronous UDP daytime client">Daytime.4 - A synchronous
UDP daytime client</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-2021 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="tutdaytime2/src.html"><img src="../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../boost_asio.html"><img src="../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tutdaytime3/src.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,169 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Source listing for Daytime.3</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../../boost_asio.html" title="Boost.Asio">
<link rel="up" href="../tutdaytime3.html" title="Daytime.3 - An asynchronous TCP daytime server">
<link rel="prev" href="../tutdaytime3.html" title="Daytime.3 - An asynchronous TCP daytime server">
<link rel="next" href="../tutdaytime4.html" title="Daytime.4 - A synchronous UDP daytime client">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../tutdaytime3.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutdaytime3.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../tutdaytime4.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_asio.tutorial.tutdaytime3.src"></a><a class="link" href="src.html" title="Source listing for Daytime.3">Source listing
for Daytime.3</a>
</h4></div></div></div>
<pre class="programlisting">//
// server.cpp
// ~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include &lt;ctime&gt;
#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;boost/bind/bind.hpp&gt;
#include &lt;boost/shared_ptr.hpp&gt;
#include &lt;boost/enable_shared_from_this.hpp&gt;
#include &lt;boost/asio.hpp&gt;
using boost::asio::ip::tcp;
std::string make_daytime_string()
{
using namespace std; // For time_t, time and ctime;
time_t now = time(0);
return ctime(&amp;now);
}
class tcp_connection
: public boost::enable_shared_from_this&lt;tcp_connection&gt;
{
public:
typedef boost::shared_ptr&lt;tcp_connection&gt; pointer;
static pointer create(boost::asio::io_context&amp; io_context)
{
return pointer(new tcp_connection(io_context));
}
tcp::socket&amp; socket()
{
return socket_;
}
void start()
{
message_ = make_daytime_string();
boost::asio::async_write(socket_, boost::asio::buffer(message_),
boost::bind(&amp;tcp_connection::handle_write, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
private:
tcp_connection(boost::asio::io_context&amp; io_context)
: socket_(io_context)
{
}
void handle_write(const boost::system::error_code&amp; /*error*/,
size_t /*bytes_transferred*/)
{
}
tcp::socket socket_;
std::string message_;
};
class tcp_server
{
public:
tcp_server(boost::asio::io_context&amp; io_context)
: io_context_(io_context),
acceptor_(io_context, tcp::endpoint(tcp::v4(), 13))
{
start_accept();
}
private:
void start_accept()
{
tcp_connection::pointer new_connection =
tcp_connection::create(io_context_);
acceptor_.async_accept(new_connection-&gt;socket(),
boost::bind(&amp;tcp_server::handle_accept, this, new_connection,
boost::asio::placeholders::error));
}
void handle_accept(tcp_connection::pointer new_connection,
const boost::system::error_code&amp; error)
{
if (!error)
{
new_connection-&gt;start();
}
start_accept();
}
boost::asio::io_context&amp; io_context_;
tcp::acceptor acceptor_;
};
int main()
{
try
{
boost::asio::io_context io_context;
tcp_server server(io_context);
io_context.run();
}
catch (std::exception&amp; e)
{
std::cerr &lt;&lt; e.what() &lt;&lt; std::endl;
}
return 0;
}
</pre>
<p>
Return to <a class="link" href="../tutdaytime3.html" title="Daytime.3 - An asynchronous TCP daytime server">Daytime.3 - An
asynchronous TCP daytime 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-2021 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="../tutdaytime3.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutdaytime3.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../tutdaytime4.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,134 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Daytime.4 - A synchronous UDP daytime client</title>
<link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../boost_asio.html" title="Boost.Asio">
<link rel="up" href="../tutorial.html" title="Tutorial">
<link rel="prev" href="tutdaytime3/src.html" title="Source listing for Daytime.3">
<link rel="next" href="tutdaytime4/src.html" title="Source listing for Daytime.4">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../boost.png"></td>
<td align="center"><a href="../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tutdaytime3/src.html"><img src="../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../boost_asio.html"><img src="../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tutdaytime4/src.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_asio.tutorial.tutdaytime4"></a><a class="link" href="tutdaytime4.html" title="Daytime.4 - A synchronous UDP daytime client">Daytime.4 - A synchronous
UDP daytime client</a>
</h3></div></div></div>
<p>
This tutorial program shows how to use asio to implement a client application
with UDP.
</p>
<pre class="programlisting">#include &lt;iostream&gt;
#include &lt;boost/array.hpp&gt;
#include &lt;boost/asio.hpp&gt;
using boost::asio::ip::udp;
</pre>
<p>
The start of the application is essentially the same as for the TCP daytime
client.
</p>
<pre class="programlisting">int main(int argc, char* argv[])
{
try
{
if (argc != 2)
{
std::cerr &lt;&lt; "Usage: client &lt;host&gt;" &lt;&lt; std::endl;
return 1;
}
boost::asio::io_context io_context;
</pre>
<p>
We use an <a class="link" href="../reference/ip__udp/resolver.html" title="ip::udp::resolver">ip::udp::resolver</a>
object to find the correct remote endpoint to use based on the host and service
names. The query is restricted to return only IPv4 endpoints by the <a class="link" href="../reference/ip__udp/v4.html" title="ip::udp::v4">ip::udp::v4()</a> argument.
</p>
<pre class="programlisting"> udp::resolver resolver(io_context);
udp::endpoint receiver_endpoint =
*resolver.resolve(udp::v4(), argv[1], "daytime").begin();
</pre>
<p>
The <a class="link" href="../reference/ip__basic_resolver/resolve.html" title="ip::basic_resolver::resolve">ip::udp::resolver::resolve()</a>
function is guaranteed to return at least one endpoint in the list if it
does not fail. This means it is safe to dereference the return value directly.
</p>
<p>
Since UDP is datagram-oriented, we will not be using a stream socket. Create
an <a class="link" href="../reference/ip__udp/socket.html" title="ip::udp::socket">ip::udp::socket</a>
and initiate contact with the remote endpoint.
</p>
<pre class="programlisting"> udp::socket socket(io_context);
socket.open(udp::v4());
boost::array&lt;char, 1&gt; send_buf = {{ 0 }};
socket.send_to(boost::asio::buffer(send_buf), receiver_endpoint);
</pre>
<p>
Now we need to be ready to accept whatever the server sends back to us. The
endpoint on our side that receives the server's response will be initialised
by <a class="link" href="../reference/basic_datagram_socket/receive_from.html" title="basic_datagram_socket::receive_from">ip::udp::socket::receive_from()</a>.
</p>
<pre class="programlisting"> boost::array&lt;char, 128&gt; recv_buf;
udp::endpoint sender_endpoint;
size_t len = socket.receive_from(
boost::asio::buffer(recv_buf), sender_endpoint);
std::cout.write(recv_buf.data(), len);
}
</pre>
<p>
Finally, handle any exceptions that may have been thrown.
</p>
<pre class="programlisting"> catch (std::exception&amp; e)
{
std::cerr &lt;&lt; e.what() &lt;&lt; std::endl;
}
return 0;
}
</pre>
<p>
See the <a class="link" href="tutdaytime4/src.html" title="Source listing for Daytime.4">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="tutdaytime3.html" title="Daytime.3 - An asynchronous TCP daytime server">Daytime.3 - An
asynchronous TCP daytime server</a>
</p>
<p>
Next: <a class="link" href="tutdaytime5.html" title="Daytime.5 - A synchronous UDP daytime server">Daytime.5 - A synchronous
UDP daytime 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-2021 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="tutdaytime3/src.html"><img src="../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../boost_asio.html"><img src="../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tutdaytime4/src.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,102 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Source listing for Daytime.4</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../../boost_asio.html" title="Boost.Asio">
<link rel="up" href="../tutdaytime4.html" title="Daytime.4 - A synchronous UDP daytime client">
<link rel="prev" href="../tutdaytime4.html" title="Daytime.4 - A synchronous UDP daytime client">
<link rel="next" href="../tutdaytime5.html" title="Daytime.5 - A synchronous UDP daytime server">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../tutdaytime4.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutdaytime4.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../tutdaytime5.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_asio.tutorial.tutdaytime4.src"></a><a class="link" href="src.html" title="Source listing for Daytime.4">Source listing
for Daytime.4</a>
</h4></div></div></div>
<pre class="programlisting">//
// client.cpp
// ~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include &lt;iostream&gt;
#include &lt;boost/array.hpp&gt;
#include &lt;boost/asio.hpp&gt;
using boost::asio::ip::udp;
int main(int argc, char* argv[])
{
try
{
if (argc != 2)
{
std::cerr &lt;&lt; "Usage: client &lt;host&gt;" &lt;&lt; std::endl;
return 1;
}
boost::asio::io_context io_context;
udp::resolver resolver(io_context);
udp::endpoint receiver_endpoint =
*resolver.resolve(udp::v4(), argv[1], "daytime").begin();
udp::socket socket(io_context);
socket.open(udp::v4());
boost::array&lt;char, 1&gt; send_buf = {{ 0 }};
socket.send_to(boost::asio::buffer(send_buf), receiver_endpoint);
boost::array&lt;char, 128&gt; recv_buf;
udp::endpoint sender_endpoint;
size_t len = socket.receive_from(
boost::asio::buffer(recv_buf), sender_endpoint);
std::cout.write(recv_buf.data(), len);
}
catch (std::exception&amp; e)
{
std::cerr &lt;&lt; e.what() &lt;&lt; std::endl;
}
return 0;
}
</pre>
<p>
Return to <a class="link" href="../tutdaytime4.html" title="Daytime.4 - A synchronous UDP daytime client">Daytime.4 - A
synchronous UDP daytime client</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-2021 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="../tutdaytime4.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutdaytime4.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../tutdaytime5.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,110 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Daytime.5 - A synchronous UDP daytime server</title>
<link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../boost_asio.html" title="Boost.Asio">
<link rel="up" href="../tutorial.html" title="Tutorial">
<link rel="prev" href="tutdaytime4/src.html" title="Source listing for Daytime.4">
<link rel="next" href="tutdaytime5/src.html" title="Source listing for Daytime.5">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../boost.png"></td>
<td align="center"><a href="../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tutdaytime4/src.html"><img src="../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../boost_asio.html"><img src="../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tutdaytime5/src.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_asio.tutorial.tutdaytime5"></a><a class="link" href="tutdaytime5.html" title="Daytime.5 - A synchronous UDP daytime server">Daytime.5 - A synchronous
UDP daytime server</a>
</h3></div></div></div>
<p>
This tutorial program shows how to use asio to implement a server application
with UDP.
</p>
<pre class="programlisting">int main()
{
try
{
boost::asio::io_context io_context;
</pre>
<p>
Create an <a class="link" href="../reference/ip__udp/socket.html" title="ip::udp::socket">ip::udp::socket</a>
object to receive requests on UDP port 13.
</p>
<pre class="programlisting"> udp::socket socket(io_context, udp::endpoint(udp::v4(), 13));
</pre>
<p>
Wait for a client to initiate contact with us. The remote_endpoint object
will be populated by <a class="link" href="../reference/basic_datagram_socket/receive_from.html" title="basic_datagram_socket::receive_from">ip::udp::socket::receive_from()</a>.
</p>
<pre class="programlisting"> for (;;)
{
boost::array&lt;char, 1&gt; recv_buf;
udp::endpoint remote_endpoint;
socket.receive_from(boost::asio::buffer(recv_buf), remote_endpoint);
</pre>
<p>
Determine what we are going to send back to the client.
</p>
<pre class="programlisting"> std::string message = make_daytime_string();
</pre>
<p>
Send the response to the remote_endpoint.
</p>
<pre class="programlisting"> boost::system::error_code ignored_error;
socket.send_to(boost::asio::buffer(message),
remote_endpoint, 0, ignored_error);
}
}
</pre>
<p>
Finally, handle any exceptions.
</p>
<pre class="programlisting"> catch (std::exception&amp; e)
{
std::cerr &lt;&lt; e.what() &lt;&lt; std::endl;
}
return 0;
}
</pre>
<p>
See the <a class="link" href="tutdaytime5/src.html" title="Source listing for Daytime.5">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="tutdaytime4.html" title="Daytime.4 - A synchronous UDP daytime client">Daytime.4 - A synchronous
UDP daytime client</a>
</p>
<p>
Next: <a class="link" href="tutdaytime6.html" title="Daytime.6 - An asynchronous UDP daytime server">Daytime.6 - An asynchronous
UDP daytime 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-2021 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="tutdaytime4/src.html"><img src="../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../boost_asio.html"><img src="../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tutdaytime5/src.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,103 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Source listing for Daytime.5</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../../boost_asio.html" title="Boost.Asio">
<link rel="up" href="../tutdaytime5.html" title="Daytime.5 - A synchronous UDP daytime server">
<link rel="prev" href="../tutdaytime5.html" title="Daytime.5 - A synchronous UDP daytime server">
<link rel="next" href="../tutdaytime6.html" title="Daytime.6 - An asynchronous UDP daytime server">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../tutdaytime5.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutdaytime5.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../tutdaytime6.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_asio.tutorial.tutdaytime5.src"></a><a class="link" href="src.html" title="Source listing for Daytime.5">Source listing
for Daytime.5</a>
</h4></div></div></div>
<pre class="programlisting">//
// server.cpp
// ~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include &lt;ctime&gt;
#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;boost/array.hpp&gt;
#include &lt;boost/asio.hpp&gt;
using boost::asio::ip::udp;
std::string make_daytime_string()
{
using namespace std; // For time_t, time and ctime;
time_t now = time(0);
return ctime(&amp;now);
}
int main()
{
try
{
boost::asio::io_context io_context;
udp::socket socket(io_context, udp::endpoint(udp::v4(), 13));
for (;;)
{
boost::array&lt;char, 1&gt; recv_buf;
udp::endpoint remote_endpoint;
socket.receive_from(boost::asio::buffer(recv_buf), remote_endpoint);
std::string message = make_daytime_string();
boost::system::error_code ignored_error;
socket.send_to(boost::asio::buffer(message),
remote_endpoint, 0, ignored_error);
}
}
catch (std::exception&amp; e)
{
std::cerr &lt;&lt; e.what() &lt;&lt; std::endl;
}
return 0;
}
</pre>
<p>
Return to <a class="link" href="../tutdaytime5.html" title="Daytime.5 - A synchronous UDP daytime server">Daytime.5 - A
synchronous UDP daytime 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-2021 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.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutdaytime5.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../tutdaytime6.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,188 @@
<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="../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../boost_asio.html" title="Boost.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="Boost C++ Libraries" width="277" height="86" src="../../../../boost.png"></td>
<td align="center"><a href="../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tutdaytime5/src.html"><img src="../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../boost_asio.html"><img src="../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tutdaytime6/src.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_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="boost_asio.tutorial.tutdaytime6.h0"></a>
<span class="phrase"><a name="boost_asio.tutorial.tutdaytime6.the_main___function"></a></span><a class="link" href="tutdaytime6.html#boost_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"> boost::asio::io_context io_context;
udp_server server(io_context);
io_context.run();
}
catch (std::exception&amp; e)
{
std::cerr &lt;&lt; e.what() &lt;&lt; std::endl;
}
return 0;
}
</pre>
<h5>
<a name="boost_asio.tutorial.tutdaytime6.h1"></a>
<span class="phrase"><a name="boost_asio.tutorial.tutdaytime6.the_udp_server_class"></a></span><a class="link" href="tutdaytime6.html#boost_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(boost::asio::io_context&amp; 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 boost::system::error_code 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(
boost::asio::buffer(recv_buffer_), remote_endpoint_,
boost::bind(&amp;udp_server::handle_receive, this,
boost::asio::placeholders::error,
boost::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 boost::system::error_code&amp; 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&lt;std::string&gt; 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(boost::asio::buffer(*message), remote_endpoint_,
boost::bind(&amp;udp_server::handle_send, this, message,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
</pre>
<p>
When initiating the asynchronous operation, and if using boost::bind(), you
must specify only the arguments that match the handler's parameter list.
In this program, both of the argument placeholders (boost::asio::placeholders::error
and boost::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&lt;std::string&gt; /*message*/,
const boost::system::error_code&amp; /*error*/,
std::size_t /*bytes_transferred*/)
{
}
udp::socket socket_;
udp::endpoint remote_endpoint_;
boost::array&lt;char, 1&gt; 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-2021 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="../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../boost_asio.html"><img src="../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tutdaytime6/src.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,139 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Source listing for Daytime.6</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../../boost_asio.html" title="Boost.Asio">
<link rel="up" href="../tutdaytime6.html" title="Daytime.6 - An asynchronous UDP daytime server">
<link rel="prev" href="../tutdaytime6.html" title="Daytime.6 - An asynchronous UDP daytime server">
<link rel="next" href="../tutdaytime7.html" title="Daytime.7 - A combined TCP/UDP asynchronous server">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../tutdaytime6.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutdaytime6.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../tutdaytime7.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_asio.tutorial.tutdaytime6.src"></a><a class="link" href="src.html" title="Source listing for Daytime.6">Source listing
for Daytime.6</a>
</h4></div></div></div>
<pre class="programlisting">//
// server.cpp
// ~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include &lt;ctime&gt;
#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;boost/array.hpp&gt;
#include &lt;boost/bind/bind.hpp&gt;
#include &lt;boost/shared_ptr.hpp&gt;
#include &lt;boost/asio.hpp&gt;
using boost::asio::ip::udp;
std::string make_daytime_string()
{
using namespace std; // For time_t, time and ctime;
time_t now = time(0);
return ctime(&amp;now);
}
class udp_server
{
public:
udp_server(boost::asio::io_context&amp; io_context)
: socket_(io_context, udp::endpoint(udp::v4(), 13))
{
start_receive();
}
private:
void start_receive()
{
socket_.async_receive_from(
boost::asio::buffer(recv_buffer_), remote_endpoint_,
boost::bind(&amp;udp_server::handle_receive, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void handle_receive(const boost::system::error_code&amp; error,
std::size_t /*bytes_transferred*/)
{
if (!error)
{
boost::shared_ptr&lt;std::string&gt; message(
new std::string(make_daytime_string()));
socket_.async_send_to(boost::asio::buffer(*message), remote_endpoint_,
boost::bind(&amp;udp_server::handle_send, this, message,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
start_receive();
}
}
void handle_send(boost::shared_ptr&lt;std::string&gt; /*message*/,
const boost::system::error_code&amp; /*error*/,
std::size_t /*bytes_transferred*/)
{
}
udp::socket socket_;
udp::endpoint remote_endpoint_;
boost::array&lt;char, 1&gt; recv_buffer_;
};
int main()
{
try
{
boost::asio::io_context io_context;
udp_server server(io_context);
io_context.run();
}
catch (std::exception&amp; e)
{
std::cerr &lt;&lt; e.what() &lt;&lt; std::endl;
}
return 0;
}
</pre>
<p>
Return to <a class="link" href="../tutdaytime6.html" title="Daytime.6 - An asynchronous UDP daytime server">Daytime.6 - An
asynchronous UDP daytime 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-2021 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="../tutdaytime6.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutdaytime6.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../tutdaytime7.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,227 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Daytime.7 - A combined TCP/UDP asynchronous server</title>
<link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../boost_asio.html" title="Boost.Asio">
<link rel="up" href="../tutorial.html" title="Tutorial">
<link rel="prev" href="tutdaytime6/src.html" title="Source listing for Daytime.6">
<link rel="next" href="tutdaytime7/src.html" title="Source listing for Daytime.7">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../boost.png"></td>
<td align="center"><a href="../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tutdaytime6/src.html"><img src="../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../boost_asio.html"><img src="../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tutdaytime7/src.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_asio.tutorial.tutdaytime7"></a><a class="link" href="tutdaytime7.html" title="Daytime.7 - A combined TCP/UDP asynchronous server">Daytime.7 - A combined
TCP/UDP asynchronous server</a>
</h3></div></div></div>
<p>
This tutorial program shows how to combine the two asynchronous servers that
we have just written, into a single server application.
</p>
<h5>
<a name="boost_asio.tutorial.tutdaytime7.h0"></a>
<span class="phrase"><a name="boost_asio.tutorial.tutdaytime7.the_main___function"></a></span><a class="link" href="tutdaytime7.html#boost_asio.tutorial.tutdaytime7.the_main___function">The
main() function</a>
</h5>
<pre class="programlisting">int main()
{
try
{
boost::asio::io_context io_context;
</pre>
<p>
We will begin by creating a server object to accept a TCP client connection.
</p>
<pre class="programlisting"> tcp_server server1(io_context);
</pre>
<p>
We also need a server object to accept a UDP client request.
</p>
<pre class="programlisting"> udp_server server2(io_context);
</pre>
<p>
We have created two lots of work for the <a class="link" href="../reference/io_context.html" title="io_context">io_context</a>
object to do.
</p>
<pre class="programlisting"> io_context.run();
}
catch (std::exception&amp; e)
{
std::cerr &lt;&lt; e.what() &lt;&lt; std::endl;
}
return 0;
}
</pre>
<h5>
<a name="boost_asio.tutorial.tutdaytime7.h1"></a>
<span class="phrase"><a name="boost_asio.tutorial.tutdaytime7.the_tcp_connection_and_tcp_server_classes"></a></span><a class="link" href="tutdaytime7.html#boost_asio.tutorial.tutdaytime7.the_tcp_connection_and_tcp_server_classes">The
tcp_connection and tcp_server classes</a>
</h5>
<p>
The following two classes are taken from <a class="link" href="tutdaytime3.html" title="Daytime.3 - An asynchronous TCP daytime server">Daytime.3</a>
.
</p>
<pre class="programlisting">class tcp_connection
: public boost::enable_shared_from_this&lt;tcp_connection&gt;
{
public:
typedef boost::shared_ptr&lt;tcp_connection&gt; pointer;
static pointer create(boost::asio::io_context&amp; io_context)
{
return pointer(new tcp_connection(io_context));
}
tcp::socket&amp; socket()
{
return socket_;
}
void start()
{
message_ = make_daytime_string();
boost::asio::async_write(socket_, boost::asio::buffer(message_),
boost::bind(&amp;tcp_connection::handle_write, shared_from_this()));
}
private:
tcp_connection(boost::asio::io_context&amp; io_context)
: socket_(io_context)
{
}
void handle_write()
{
}
tcp::socket socket_;
std::string message_;
};
class tcp_server
{
public:
tcp_server(boost::asio::io_context&amp; io_context)
: io_context_(io_context),
acceptor_(io_context, tcp::endpoint(tcp::v4(), 13))
{
start_accept();
}
private:
void start_accept()
{
tcp_connection::pointer new_connection =
tcp_connection::create(io_context_);
acceptor_.async_accept(new_connection-&gt;socket(),
boost::bind(&amp;tcp_server::handle_accept, this, new_connection,
boost::asio::placeholders::error));
}
void handle_accept(tcp_connection::pointer new_connection,
const boost::system::error_code&amp; error)
{
if (!error)
{
new_connection-&gt;start();
}
start_accept();
}
boost::asio::io_context&amp; io_context_;
tcp::acceptor acceptor_;
};
</pre>
<h5>
<a name="boost_asio.tutorial.tutdaytime7.h2"></a>
<span class="phrase"><a name="boost_asio.tutorial.tutdaytime7.the_udp_server_class"></a></span><a class="link" href="tutdaytime7.html#boost_asio.tutorial.tutdaytime7.the_udp_server_class">The udp_server
class</a>
</h5>
<p>
Similarly, this next class is taken from the <a class="link" href="tutdaytime6.html" title="Daytime.6 - An asynchronous UDP daytime server">previous
tutorial step</a> .
</p>
<pre class="programlisting">class udp_server
{
public:
udp_server(boost::asio::io_context&amp; io_context)
: socket_(io_context, udp::endpoint(udp::v4(), 13))
{
start_receive();
}
private:
void start_receive()
{
socket_.async_receive_from(
boost::asio::buffer(recv_buffer_), remote_endpoint_,
boost::bind(&amp;udp_server::handle_receive, this,
boost::asio::placeholders::error));
}
void handle_receive(const boost::system::error_code&amp; error)
{
if (!error)
{
boost::shared_ptr&lt;std::string&gt; message(
new std::string(make_daytime_string()));
socket_.async_send_to(boost::asio::buffer(*message), remote_endpoint_,
boost::bind(&amp;udp_server::handle_send, this, message));
start_receive();
}
}
void handle_send(boost::shared_ptr&lt;std::string&gt; /*message*/)
{
}
udp::socket socket_;
udp::endpoint remote_endpoint_;
boost::array&lt;char, 1&gt; recv_buffer_;
};
</pre>
<p>
See the <a class="link" href="tutdaytime7/src.html" title="Source listing for Daytime.7">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="tutdaytime6.html" title="Daytime.6 - An asynchronous UDP daytime server">Daytime.6 - An
asynchronous UDP daytime 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-2021 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="tutdaytime6/src.html"><img src="../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../boost_asio.html"><img src="../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tutdaytime7/src.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,210 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Source listing for Daytime.7</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../../boost_asio.html" title="Boost.Asio">
<link rel="up" href="../tutdaytime7.html" title="Daytime.7 - A combined TCP/UDP asynchronous server">
<link rel="prev" href="../tutdaytime7.html" title="Daytime.7 - A combined TCP/UDP asynchronous server">
<link rel="next" href="../../examples.html" title="Examples">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../tutdaytime7.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutdaytime7.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../../examples.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_asio.tutorial.tutdaytime7.src"></a><a class="link" href="src.html" title="Source listing for Daytime.7">Source listing
for Daytime.7</a>
</h4></div></div></div>
<pre class="programlisting">//
// server.cpp
// ~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include &lt;ctime&gt;
#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;boost/array.hpp&gt;
#include &lt;boost/bind/bind.hpp&gt;
#include &lt;boost/shared_ptr.hpp&gt;
#include &lt;boost/enable_shared_from_this.hpp&gt;
#include &lt;boost/asio.hpp&gt;
using boost::asio::ip::tcp;
using boost::asio::ip::udp;
std::string make_daytime_string()
{
using namespace std; // For time_t, time and ctime;
time_t now = time(0);
return ctime(&amp;now);
}
class tcp_connection
: public boost::enable_shared_from_this&lt;tcp_connection&gt;
{
public:
typedef boost::shared_ptr&lt;tcp_connection&gt; pointer;
static pointer create(boost::asio::io_context&amp; io_context)
{
return pointer(new tcp_connection(io_context));
}
tcp::socket&amp; socket()
{
return socket_;
}
void start()
{
message_ = make_daytime_string();
boost::asio::async_write(socket_, boost::asio::buffer(message_),
boost::bind(&amp;tcp_connection::handle_write, shared_from_this()));
}
private:
tcp_connection(boost::asio::io_context&amp; io_context)
: socket_(io_context)
{
}
void handle_write()
{
}
tcp::socket socket_;
std::string message_;
};
class tcp_server
{
public:
tcp_server(boost::asio::io_context&amp; io_context)
: io_context_(io_context),
acceptor_(io_context, tcp::endpoint(tcp::v4(), 13))
{
start_accept();
}
private:
void start_accept()
{
tcp_connection::pointer new_connection =
tcp_connection::create(io_context_);
acceptor_.async_accept(new_connection-&gt;socket(),
boost::bind(&amp;tcp_server::handle_accept, this, new_connection,
boost::asio::placeholders::error));
}
void handle_accept(tcp_connection::pointer new_connection,
const boost::system::error_code&amp; error)
{
if (!error)
{
new_connection-&gt;start();
}
start_accept();
}
boost::asio::io_context&amp; io_context_;
tcp::acceptor acceptor_;
};
class udp_server
{
public:
udp_server(boost::asio::io_context&amp; io_context)
: socket_(io_context, udp::endpoint(udp::v4(), 13))
{
start_receive();
}
private:
void start_receive()
{
socket_.async_receive_from(
boost::asio::buffer(recv_buffer_), remote_endpoint_,
boost::bind(&amp;udp_server::handle_receive, this,
boost::asio::placeholders::error));
}
void handle_receive(const boost::system::error_code&amp; error)
{
if (!error)
{
boost::shared_ptr&lt;std::string&gt; message(
new std::string(make_daytime_string()));
socket_.async_send_to(boost::asio::buffer(*message), remote_endpoint_,
boost::bind(&amp;udp_server::handle_send, this, message));
start_receive();
}
}
void handle_send(boost::shared_ptr&lt;std::string&gt; /*message*/)
{
}
udp::socket socket_;
udp::endpoint remote_endpoint_;
boost::array&lt;char, 1&gt; recv_buffer_;
};
int main()
{
try
{
boost::asio::io_context io_context;
tcp_server server1(io_context);
udp_server server2(io_context);
io_context.run();
}
catch (std::exception&amp; e)
{
std::cerr &lt;&lt; e.what() &lt;&lt; std::endl;
}
return 0;
}
</pre>
<p>
Return to <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-2021 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="../tutdaytime7.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutdaytime7.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../../examples.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,112 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Timer.1 - Using a timer synchronously</title>
<link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../boost_asio.html" title="Boost.Asio">
<link rel="up" href="../tutorial.html" title="Tutorial">
<link rel="prev" href="../tutorial.html" title="Tutorial">
<link rel="next" href="tuttimer1/src.html" title="Source listing for Timer.1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../boost.png"></td>
<td align="center"><a href="../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../tutorial.html"><img src="../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../boost_asio.html"><img src="../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tuttimer1/src.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_asio.tutorial.tuttimer1"></a><a class="link" href="tuttimer1.html" title="Timer.1 - Using a timer synchronously">Timer.1 - Using a timer
synchronously</a>
</h3></div></div></div>
<p>
This tutorial program introduces asio by showing how to perform a blocking
wait on a timer.
</p>
<p>
We start by including the necessary header files.
</p>
<p>
All of the asio classes can be used by simply including the <code class="computeroutput">"asio.hpp"</code>
header file.
</p>
<pre class="programlisting">#include &lt;iostream&gt;
#include &lt;boost/asio.hpp&gt;
</pre>
<p>
All programs that use asio need to have at least one I/O execution context,
such as an <a class="link" href="../reference/io_context.html" title="io_context">io_context</a>
or <a class="link" href="../reference/thread_pool.html" title="thread_pool">thread_pool</a> object.
An I/O execution context provides access to I/O functionality. We declare
an object of type <a class="link" href="../reference/io_context.html" title="io_context">io_context</a>
first thing in the main function.
</p>
<pre class="programlisting">int main()
{
boost::asio::io_context io;
</pre>
<p>
Next we declare an object of type boost::asio::steady_timer. The core asio
classes that provide I/O functionality (or as in this case timer functionality)
always take a reference to an io_context as their first constructor argument.
The second argument to the constructor sets the timer to expire 5 seconds
from now.
</p>
<pre class="programlisting"> boost::asio::steady_timer t(io, boost::asio::chrono::seconds(5));
</pre>
<p>
In this simple example we perform a blocking wait on the timer. That is,
the call to <a class="link" href="../reference/basic_waitable_timer/wait.html" title="basic_waitable_timer::wait">steady_timer::wait()</a>
will not return until the timer has expired, 5 seconds after it was created
(i.e. not from when the wait starts).
</p>
<p>
A timer is always in one of two states: "expired" or "not
expired". If the <a class="link" href="../reference/basic_waitable_timer/wait.html" title="basic_waitable_timer::wait">steady_timer::wait()</a>
function is called on an expired timer, it will return immediately.
</p>
<pre class="programlisting"> t.wait();
</pre>
<p>
Finally we print the obligatory <code class="computeroutput">"Hello, world!"</code> message
to show when the timer has expired.
</p>
<pre class="programlisting"> std::cout &lt;&lt; "Hello, world!" &lt;&lt; std::endl;
return 0;
}
</pre>
<p>
See the <a class="link" href="tuttimer1/src.html" title="Source listing for Timer.1">full source listing</a>
</p>
<p>
Return to the <a class="link" href="../tutorial.html" title="Tutorial">tutorial index</a>
</p>
<p>
Next: <a class="link" href="tuttimer2.html" title="Timer.2 - Using a timer asynchronously">Timer.2 - Using a timer
asynchronously</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-2021 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="../tutorial.html"><img src="../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../boost_asio.html"><img src="../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tuttimer1/src.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,74 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Source listing for Timer.1</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../../boost_asio.html" title="Boost.Asio">
<link rel="up" href="../tuttimer1.html" title="Timer.1 - Using a timer synchronously">
<link rel="prev" href="../tuttimer1.html" title="Timer.1 - Using a timer synchronously">
<link rel="next" href="../tuttimer2.html" title="Timer.2 - Using a timer asynchronously">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../tuttimer1.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tuttimer1.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../tuttimer2.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_asio.tutorial.tuttimer1.src"></a><a class="link" href="src.html" title="Source listing for Timer.1">Source listing for
Timer.1</a>
</h4></div></div></div>
<pre class="programlisting">//
// timer.cpp
// ~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include &lt;iostream&gt;
#include &lt;boost/asio.hpp&gt;
int main()
{
boost::asio::io_context io;
boost::asio::steady_timer t(io, boost::asio::chrono::seconds(5));
t.wait();
std::cout &lt;&lt; "Hello, world!" &lt;&lt; std::endl;
return 0;
}
</pre>
<p>
Return to <a class="link" href="../tuttimer1.html" title="Timer.1 - Using a timer synchronously">Timer.1 - Using
a timer synchronously</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-2021 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="../tuttimer1.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tuttimer1.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../tuttimer2.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,122 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Timer.2 - Using a timer asynchronously</title>
<link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../boost_asio.html" title="Boost.Asio">
<link rel="up" href="../tutorial.html" title="Tutorial">
<link rel="prev" href="tuttimer1/src.html" title="Source listing for Timer.1">
<link rel="next" href="tuttimer2/src.html" title="Source listing for Timer.2">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../boost.png"></td>
<td align="center"><a href="../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tuttimer1/src.html"><img src="../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../boost_asio.html"><img src="../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tuttimer2/src.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_asio.tutorial.tuttimer2"></a><a class="link" href="tuttimer2.html" title="Timer.2 - Using a timer asynchronously">Timer.2 - Using a timer
asynchronously</a>
</h3></div></div></div>
<p>
This tutorial program demonstrates how to use asio's asynchronous callback
functionality by modifying the program from tutorial Timer.1 to perform an
asynchronous wait on the timer.
</p>
<pre class="programlisting">#include &lt;iostream&gt;
#include &lt;boost/asio.hpp&gt;
</pre>
<p>
Using asio's asynchronous functionality means having a callback function
that will be called when an asynchronous operation completes. In this program
we define a function called <code class="computeroutput">print</code> to be called when the asynchronous
wait finishes.
</p>
<pre class="programlisting">void print(const boost::system::error_code&amp; /*e*/)
{
std::cout &lt;&lt; "Hello, world!" &lt;&lt; std::endl;
}
int main()
{
boost::asio::io_context io;
boost::asio::steady_timer t(io, boost::asio::chrono::seconds(5));
</pre>
<p>
Next, instead of doing a blocking wait as in tutorial Timer.1, we call the
<a class="link" href="../reference/basic_waitable_timer/async_wait.html" title="basic_waitable_timer::async_wait">steady_timer::async_wait()</a>
function to perform an asynchronous wait. When calling this function we pass
the <code class="computeroutput">print</code> callback handler that was defined above.
</p>
<pre class="programlisting"> t.async_wait(&amp;print);
</pre>
<p>
Finally, we must call the <a class="link" href="../reference/io_context/run.html" title="io_context::run">io_context::run()</a>
member function on the io_context object.
</p>
<p>
The asio library provides a guarantee that callback handlers will only be
called from threads that are currently calling <a class="link" href="../reference/io_context/run.html" title="io_context::run">io_context::run()</a>.
Therefore unless the <a class="link" href="../reference/io_context/run.html" title="io_context::run">io_context::run()</a>
function is called the callback for the asynchronous wait completion will
never be invoked.
</p>
<p>
The <a class="link" href="../reference/io_context/run.html" title="io_context::run">io_context::run()</a>
function will also continue to run while there is still "work"
to do. In this example, the work is the asynchronous wait on the timer, so
the call will not return until the timer has expired and the callback has
completed.
</p>
<p>
It is important to remember to give the io_context some work to do before
calling <a class="link" href="../reference/io_context/run.html" title="io_context::run">io_context::run()</a>.
For example, if we had omitted the above call to <a class="link" href="../reference/basic_waitable_timer/async_wait.html" title="basic_waitable_timer::async_wait">steady_timer::async_wait()</a>,
the io_context would not have had any work to do, and consequently <a class="link" href="../reference/io_context/run.html" title="io_context::run">io_context::run()</a> would
have returned immediately.
</p>
<pre class="programlisting"> io.run();
return 0;
}
</pre>
<p>
See the <a class="link" href="tuttimer2/src.html" title="Source listing for Timer.2">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="tuttimer1.html" title="Timer.1 - Using a timer synchronously">Timer.1 - Using a
timer synchronously</a>
</p>
<p>
Next: <a class="link" href="tuttimer3.html" title="Timer.3 - Binding arguments to a handler">Timer.3 - Binding arguments
to a handler</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-2021 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="tuttimer1/src.html"><img src="../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../boost_asio.html"><img src="../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tuttimer2/src.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,79 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Source listing for Timer.2</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../../boost_asio.html" title="Boost.Asio">
<link rel="up" href="../tuttimer2.html" title="Timer.2 - Using a timer asynchronously">
<link rel="prev" href="../tuttimer2.html" title="Timer.2 - Using a timer asynchronously">
<link rel="next" href="../tuttimer3.html" title="Timer.3 - Binding arguments to a handler">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../tuttimer2.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tuttimer2.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../tuttimer3.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_asio.tutorial.tuttimer2.src"></a><a class="link" href="src.html" title="Source listing for Timer.2">Source listing for
Timer.2</a>
</h4></div></div></div>
<pre class="programlisting">//
// timer.cpp
// ~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include &lt;iostream&gt;
#include &lt;boost/asio.hpp&gt;
void print(const boost::system::error_code&amp; /*e*/)
{
std::cout &lt;&lt; "Hello, world!" &lt;&lt; std::endl;
}
int main()
{
boost::asio::io_context io;
boost::asio::steady_timer t(io, boost::asio::chrono::seconds(5));
t.async_wait(&amp;print);
io.run();
return 0;
}
</pre>
<p>
Return to <a class="link" href="../tuttimer2.html" title="Timer.2 - Using a timer asynchronously">Timer.2 - Using
a timer asynchronously</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-2021 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="../tuttimer2.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tuttimer2.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../tuttimer3.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,166 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Timer.3 - Binding arguments to a handler</title>
<link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../boost_asio.html" title="Boost.Asio">
<link rel="up" href="../tutorial.html" title="Tutorial">
<link rel="prev" href="tuttimer2/src.html" title="Source listing for Timer.2">
<link rel="next" href="tuttimer3/src.html" title="Source listing for Timer.3">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../boost.png"></td>
<td align="center"><a href="../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tuttimer2/src.html"><img src="../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../boost_asio.html"><img src="../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tuttimer3/src.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_asio.tutorial.tuttimer3"></a><a class="link" href="tuttimer3.html" title="Timer.3 - Binding arguments to a handler">Timer.3 - Binding arguments
to a handler</a>
</h3></div></div></div>
<p>
In this tutorial we will modify the program from tutorial Timer.2 so that
the timer fires once a second. This will show how to pass additional parameters
to your handler function.
</p>
<pre class="programlisting">#include &lt;iostream&gt;
#include &lt;boost/asio.hpp&gt;
#include &lt;boost/bind/bind.hpp&gt;
</pre>
<p>
To implement a repeating timer using asio you need to change the timer's
expiry time in your callback function, and to then start a new asynchronous
wait. Obviously this means that the callback function will need to be able
to access the timer object. To this end we add two new parameters to the
<code class="computeroutput">print</code> function:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
A pointer to a timer object.
</li>
<li class="listitem">
A counter so that we can stop the program when the timer fires for the
sixth time.
</li>
</ul></div>
<pre class="programlisting">void print(const boost::system::error_code&amp; /*e*/,
boost::asio::steady_timer* t, int* count)
{
</pre>
<p>
As mentioned above, this tutorial program uses a counter to stop running
when the timer fires for the sixth time. However you will observe that there
is no explicit call to ask the io_context to stop. Recall that in tutorial
Timer.2 we learnt that the <a class="link" href="../reference/io_context/run.html" title="io_context::run">io_context::run()</a>
function completes when there is no more "work" to do. By not starting
a new asynchronous wait on the timer when <code class="computeroutput">count</code> reaches 5, the
io_context will run out of work and stop running.
</p>
<pre class="programlisting"> if (*count &lt; 5)
{
std::cout &lt;&lt; *count &lt;&lt; std::endl;
++(*count);
</pre>
<p>
Next we move the expiry time for the timer along by one second from the previous
expiry time. By calculating the new expiry time relative to the old, we can
ensure that the timer does not drift away from the whole-second mark due
to any delays in processing the handler.
</p>
<pre class="programlisting"> t-&gt;expires_at(t-&gt;expiry() + boost::asio::chrono::seconds(1));
</pre>
<p>
Then we start a new asynchronous wait on the timer. As you can see, the boost::bind()
function is used to associate the extra parameters with your callback handler.
The <a class="link" href="../reference/basic_waitable_timer/async_wait.html" title="basic_waitable_timer::async_wait">steady_timer::async_wait()</a>
function expects a handler function (or function object) with the signature
<code class="computeroutput">void(const boost::system::error_code&amp;)</code>. Binding the additional
parameters converts your <code class="computeroutput">print</code> function into a function object
that matches the signature correctly.
</p>
<p>
See the <a href="http://www.boost.org/libs/bind/bind.html" target="_top">Boost.Bind
documentation</a> for more information on how to use boost::bind().
</p>
<p>
In this example, the boost::asio::placeholders::error argument to boost::bind()
is a named placeholder for the error object passed to the handler. When initiating
the asynchronous operation, and if using boost::bind(), you must specify
only the arguments that match the handler's parameter list. In tutorial Timer.4
you will see that this placeholder may be elided if the parameter is not
needed by the callback handler.
</p>
<pre class="programlisting"> t-&gt;async_wait(boost::bind(print,
boost::asio::placeholders::error, t, count));
}
}
int main()
{
boost::asio::io_context io;
</pre>
<p>
A new <code class="computeroutput">count</code> variable is added so that we can stop the program
when the timer fires for the sixth time.
</p>
<pre class="programlisting"> int count = 0;
boost::asio::steady_timer t(io, boost::asio::chrono::seconds(1));
</pre>
<p>
As in Step 4, when making the call to <a class="link" href="../reference/basic_waitable_timer/async_wait.html" title="basic_waitable_timer::async_wait">steady_timer::async_wait()</a>
from <code class="computeroutput">main</code> we bind the additional parameters needed for the
<code class="computeroutput">print</code> function.
</p>
<pre class="programlisting"> t.async_wait(boost::bind(print,
boost::asio::placeholders::error, &amp;t, &amp;count));
io.run();
</pre>
<p>
Finally, just to prove that the <code class="computeroutput">count</code> variable was being used
in the <code class="computeroutput">print</code> handler function, we will print out its new value.
</p>
<pre class="programlisting"> std::cout &lt;&lt; "Final count is " &lt;&lt; count &lt;&lt; std::endl;
return 0;
}
</pre>
<p>
See the <a class="link" href="tuttimer3/src.html" title="Source listing for Timer.3">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="tuttimer2.html" title="Timer.2 - Using a timer asynchronously">Timer.2 - Using a
timer asynchronously</a>
</p>
<p>
Next: <a class="link" href="tuttimer4.html" title="Timer.4 - Using a member function as a handler">Timer.4 - Using a member
function as a handler</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-2021 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="tuttimer2/src.html"><img src="../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../boost_asio.html"><img src="../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tuttimer3/src.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,93 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Source listing for Timer.3</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../../boost_asio.html" title="Boost.Asio">
<link rel="up" href="../tuttimer3.html" title="Timer.3 - Binding arguments to a handler">
<link rel="prev" href="../tuttimer3.html" title="Timer.3 - Binding arguments to a handler">
<link rel="next" href="../tuttimer4.html" title="Timer.4 - Using a member function as a handler">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../tuttimer3.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tuttimer3.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../tuttimer4.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_asio.tutorial.tuttimer3.src"></a><a class="link" href="src.html" title="Source listing for Timer.3">Source listing for
Timer.3</a>
</h4></div></div></div>
<pre class="programlisting">//
// timer.cpp
// ~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include &lt;iostream&gt;
#include &lt;boost/asio.hpp&gt;
#include &lt;boost/bind/bind.hpp&gt;
void print(const boost::system::error_code&amp; /*e*/,
boost::asio::steady_timer* t, int* count)
{
if (*count &lt; 5)
{
std::cout &lt;&lt; *count &lt;&lt; std::endl;
++(*count);
t-&gt;expires_at(t-&gt;expiry() + boost::asio::chrono::seconds(1));
t-&gt;async_wait(boost::bind(print,
boost::asio::placeholders::error, t, count));
}
}
int main()
{
boost::asio::io_context io;
int count = 0;
boost::asio::steady_timer t(io, boost::asio::chrono::seconds(1));
t.async_wait(boost::bind(print,
boost::asio::placeholders::error, &amp;t, &amp;count));
io.run();
std::cout &lt;&lt; "Final count is " &lt;&lt; count &lt;&lt; std::endl;
return 0;
}
</pre>
<p>
Return to <a class="link" href="../tuttimer3.html" title="Timer.3 - Binding arguments to a handler">Timer.3 - Binding
arguments to a handler</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-2021 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="../tuttimer3.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tuttimer3.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../tuttimer4.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,146 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Timer.4 - Using a member function as a handler</title>
<link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../boost_asio.html" title="Boost.Asio">
<link rel="up" href="../tutorial.html" title="Tutorial">
<link rel="prev" href="tuttimer3/src.html" title="Source listing for Timer.3">
<link rel="next" href="tuttimer4/src.html" title="Source listing for Timer.4">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../boost.png"></td>
<td align="center"><a href="../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tuttimer3/src.html"><img src="../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../boost_asio.html"><img src="../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tuttimer4/src.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_asio.tutorial.tuttimer4"></a><a class="link" href="tuttimer4.html" title="Timer.4 - Using a member function as a handler">Timer.4 - Using a member
function as a handler</a>
</h3></div></div></div>
<p>
In this tutorial we will see how to use a class member function as a callback
handler. The program should execute identically to the tutorial program from
tutorial Timer.3.
</p>
<pre class="programlisting">#include &lt;iostream&gt;
#include &lt;boost/asio.hpp&gt;
#include &lt;boost/bind/bind.hpp&gt;
</pre>
<p>
Instead of defining a free function <code class="computeroutput">print</code> as the callback handler,
as we did in the earlier tutorial programs, we now define a class called
<code class="computeroutput">printer</code>.
</p>
<pre class="programlisting">class printer
{
public:
</pre>
<p>
The constructor of this class will take a reference to the io_context object
and use it when initialising the <code class="computeroutput">timer_</code> member. The counter
used to shut down the program is now also a member of the class.
</p>
<pre class="programlisting"> printer(boost::asio::io_context&amp; io)
: timer_(io, boost::asio::chrono::seconds(1)),
count_(0)
{
</pre>
<p>
The boost::bind() function works just as well with class member functions
as with free functions. Since all non-static class member functions have
an implicit <code class="computeroutput">this</code> parameter, we need to bind <code class="computeroutput">this</code>
to the function. As in tutorial Timer.3, boost::bind() converts our callback
handler (now a member function) into a function object that can be invoked
as though it has the signature <code class="computeroutput">void(const boost::system::error_code&amp;)</code>.
</p>
<p>
You will note that the boost::asio::placeholders::error placeholder is not
specified here, as the <code class="computeroutput">print</code> member function does not accept
an error object as a parameter.
</p>
<pre class="programlisting"> timer_.async_wait(boost::bind(&amp;printer::print, this));
}
</pre>
<p>
In the class destructor we will print out the final value of the counter.
</p>
<pre class="programlisting"> ~printer()
{
std::cout &lt;&lt; "Final count is " &lt;&lt; count_ &lt;&lt; std::endl;
}
</pre>
<p>
The <code class="computeroutput">print</code> member function is very similar to the <code class="computeroutput">print</code>
function from tutorial Timer.3, except that it now operates on the class
data members instead of having the timer and counter passed in as parameters.
</p>
<pre class="programlisting"> void print()
{
if (count_ &lt; 5)
{
std::cout &lt;&lt; count_ &lt;&lt; std::endl;
++count_;
timer_.expires_at(timer_.expiry() + boost::asio::chrono::seconds(1));
timer_.async_wait(boost::bind(&amp;printer::print, this));
}
}
private:
boost::asio::steady_timer timer_;
int count_;
};
</pre>
<p>
The <code class="computeroutput">main</code> function is much simpler than before, as it now declares
a local <code class="computeroutput">printer</code> object before running the io_context as normal.
</p>
<pre class="programlisting">int main()
{
boost::asio::io_context io;
printer p(io);
io.run();
return 0;
}
</pre>
<p>
See the <a class="link" href="tuttimer4/src.html" title="Source listing for Timer.4">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="tuttimer3.html" title="Timer.3 - Binding arguments to a handler">Timer.3 - Binding
arguments to a handler</a>
</p>
<p>
Next: <a class="link" href="tuttimer5.html" title="Timer.5 - Synchronising handlers in multithreaded programs">Timer.5 - Synchronising
handlers in multithreaded programs</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-2021 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="tuttimer3/src.html"><img src="../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../boost_asio.html"><img src="../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tuttimer4/src.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,104 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Source listing for Timer.4</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../../boost_asio.html" title="Boost.Asio">
<link rel="up" href="../tuttimer4.html" title="Timer.4 - Using a member function as a handler">
<link rel="prev" href="../tuttimer4.html" title="Timer.4 - Using a member function as a handler">
<link rel="next" href="../tuttimer5.html" title="Timer.5 - Synchronising handlers in multithreaded programs">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../tuttimer4.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tuttimer4.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../tuttimer5.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_asio.tutorial.tuttimer4.src"></a><a class="link" href="src.html" title="Source listing for Timer.4">Source listing for
Timer.4</a>
</h4></div></div></div>
<pre class="programlisting">//
// timer.cpp
// ~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include &lt;iostream&gt;
#include &lt;boost/asio.hpp&gt;
#include &lt;boost/bind/bind.hpp&gt;
class printer
{
public:
printer(boost::asio::io_context&amp; io)
: timer_(io, boost::asio::chrono::seconds(1)),
count_(0)
{
timer_.async_wait(boost::bind(&amp;printer::print, this));
}
~printer()
{
std::cout &lt;&lt; "Final count is " &lt;&lt; count_ &lt;&lt; std::endl;
}
void print()
{
if (count_ &lt; 5)
{
std::cout &lt;&lt; count_ &lt;&lt; std::endl;
++count_;
timer_.expires_at(timer_.expiry() + boost::asio::chrono::seconds(1));
timer_.async_wait(boost::bind(&amp;printer::print, this));
}
}
private:
boost::asio::steady_timer timer_;
int count_;
};
int main()
{
boost::asio::io_context io;
printer p(io);
io.run();
return 0;
}
</pre>
<p>
Return to <a class="link" href="../tuttimer4.html" title="Timer.4 - Using a member function as a handler">Timer.4 - Using
a member function as a handler</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-2021 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="../tuttimer4.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tuttimer4.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../tuttimer5.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,207 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Timer.5 - Synchronising handlers in multithreaded programs</title>
<link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../boost_asio.html" title="Boost.Asio">
<link rel="up" href="../tutorial.html" title="Tutorial">
<link rel="prev" href="tuttimer4/src.html" title="Source listing for Timer.4">
<link rel="next" href="tuttimer5/src.html" title="Source listing for Timer.5">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../boost.png"></td>
<td align="center"><a href="../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tuttimer4/src.html"><img src="../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../boost_asio.html"><img src="../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tuttimer5/src.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_asio.tutorial.tuttimer5"></a><a class="link" href="tuttimer5.html" title="Timer.5 - Synchronising handlers in multithreaded programs">Timer.5 - Synchronising
handlers in multithreaded programs</a>
</h3></div></div></div>
<p>
This tutorial demonstrates the use of the <a class="link" href="../reference/strand.html" title="strand">strand</a>
class template to synchronise callback handlers in a multithreaded program.
</p>
<p>
The previous four tutorials avoided the issue of handler synchronisation
by calling the <a class="link" href="../reference/io_context/run.html" title="io_context::run">io_context::run()</a>
function from one thread only. As you already know, the asio library provides
a guarantee that callback handlers will only be called from threads that
are currently calling <a class="link" href="../reference/io_context/run.html" title="io_context::run">io_context::run()</a>.
Consequently, calling <a class="link" href="../reference/io_context/run.html" title="io_context::run">io_context::run()</a>
from only one thread ensures that callback handlers cannot run concurrently.
</p>
<p>
The single threaded approach is usually the best place to start when developing
applications using asio. The downside is the limitations it places on programs,
particularly servers, including:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
Poor responsiveness when handlers can take a long time to complete.
</li>
<li class="listitem">
An inability to scale on multiprocessor systems.
</li>
</ul></div>
<p>
If you find yourself running into these limitations, an alternative approach
is to have a pool of threads calling <a class="link" href="../reference/io_context/run.html" title="io_context::run">io_context::run()</a>.
However, as this allows handlers to execute concurrently, we need a method
of synchronisation when handlers might be accessing a shared, thread-unsafe
resource.
</p>
<pre class="programlisting">#include &lt;iostream&gt;
#include &lt;boost/asio.hpp&gt;
#include &lt;boost/thread/thread.hpp&gt;
#include &lt;boost/bind/bind.hpp&gt;
</pre>
<p>
We start by defining a class called <code class="computeroutput">printer</code>, similar to the
class in the previous tutorial. This class will extend the previous tutorial
by running two timers in parallel.
</p>
<pre class="programlisting">class printer
{
public:
</pre>
<p>
In addition to initialising a pair of boost::asio::steady_timer members,
the constructor initialises the <code class="computeroutput">strand_</code> member, an object of
type boost::asio::strand&lt;boost::asio::io_context::executor_type&gt;.
</p>
<p>
The <a class="link" href="../reference/strand.html" title="strand">strand</a> class template
is an executor adapter that guarantees that, for those handlers that are
dispatched through it, an executing handler will be allowed to complete before
the next one is started. This is guaranteed irrespective of the number of
threads that are calling <a class="link" href="../reference/io_context/run.html" title="io_context::run">io_context::run()</a>.
Of course, the handlers may still execute concurrently with other handlers
that were not dispatched through an <a class="link" href="../reference/strand.html" title="strand">strand</a>,
or were dispatched through a different <a class="link" href="../reference/strand.html" title="strand">strand</a>
object.
</p>
<pre class="programlisting"> printer(boost::asio::io_context&amp; io)
: strand_(boost::asio::make_strand(io)),
timer1_(io, boost::asio::chrono::seconds(1)),
timer2_(io, boost::asio::chrono::seconds(1)),
count_(0)
{
</pre>
<p>
When initiating the asynchronous operations, each callback handler is "bound"
to an boost::asio::strand&lt;boost::asio::io_context::executor_type&gt; object.
The boost::asio::bind_executor() function returns a new handler that automatically
dispatches its contained handler through the <a class="link" href="../reference/strand.html" title="strand">strand</a>
object. By binding the handlers to the same <a class="link" href="../reference/strand.html" title="strand">strand</a>,
we are ensuring that they cannot execute concurrently.
</p>
<pre class="programlisting"> timer1_.async_wait(boost::asio::bind_executor(strand_,
boost::bind(&amp;printer::print1, this)));
timer2_.async_wait(boost::asio::bind_executor(strand_,
boost::bind(&amp;printer::print2, this)));
}
~printer()
{
std::cout &lt;&lt; "Final count is " &lt;&lt; count_ &lt;&lt; std::endl;
}
</pre>
<p>
In a multithreaded program, the handlers for asynchronous operations should
be synchronised if they access shared resources. In this tutorial, the shared
resources used by the handlers (<code class="computeroutput">print1</code> and <code class="computeroutput">print2</code>)
are <code class="computeroutput">std::cout</code> and the <code class="computeroutput">count_</code> data member.
</p>
<pre class="programlisting"> void print1()
{
if (count_ &lt; 10)
{
std::cout &lt;&lt; "Timer 1: " &lt;&lt; count_ &lt;&lt; std::endl;
++count_;
timer1_.expires_at(timer1_.expiry() + boost::asio::chrono::seconds(1));
timer1_.async_wait(boost::asio::bind_executor(strand_,
boost::bind(&amp;printer::print1, this)));
}
}
void print2()
{
if (count_ &lt; 10)
{
std::cout &lt;&lt; "Timer 2: " &lt;&lt; count_ &lt;&lt; std::endl;
++count_;
timer2_.expires_at(timer2_.expiry() + boost::asio::chrono::seconds(1));
timer2_.async_wait(boost::asio::bind_executor(strand_,
boost::bind(&amp;printer::print2, this)));
}
}
private:
boost::asio::strand&lt;boost::asio::io_context::executor_type&gt; strand_;
boost::asio::steady_timer timer1_;
boost::asio::steady_timer timer2_;
int count_;
};
</pre>
<p>
The <code class="computeroutput">main</code> function now causes <a class="link" href="../reference/io_context/run.html" title="io_context::run">io_context::run()</a>
to be called from two threads: the main thread and one additional thread.
This is accomplished using an boost::thread object.
</p>
<p>
Just as it would with a call from a single thread, concurrent calls to <a class="link" href="../reference/io_context/run.html" title="io_context::run">io_context::run()</a> will
continue to execute while there is "work" left to do. The background
thread will not exit until all asynchronous operations have completed.
</p>
<pre class="programlisting">int main()
{
boost::asio::io_context io;
printer p(io);
boost::thread t(boost::bind(&amp;boost::asio::io_context::run, &amp;io));
io.run();
t.join();
return 0;
}
</pre>
<p>
See the <a class="link" href="tuttimer5/src.html" title="Source listing for Timer.5">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="tuttimer4.html" title="Timer.4 - Using a member function as a handler">Timer.4 - Using a
member function as a handler</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-2021 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="tuttimer4/src.html"><img src="../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../boost_asio.html"><img src="../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tuttimer5/src.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,131 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Source listing for Timer.5</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../../boost_asio.html" title="Boost.Asio">
<link rel="up" href="../tuttimer5.html" title="Timer.5 - Synchronising handlers in multithreaded programs">
<link rel="prev" href="../tuttimer5.html" title="Timer.5 - Synchronising handlers in multithreaded programs">
<link rel="next" href="../tutdaytime1.html" title="Daytime.1 - A synchronous TCP daytime client">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../tuttimer5.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tuttimer5.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../tutdaytime1.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_asio.tutorial.tuttimer5.src"></a><a class="link" href="src.html" title="Source listing for Timer.5">Source listing for
Timer.5</a>
</h4></div></div></div>
<pre class="programlisting">//
// timer.cpp
// ~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include &lt;iostream&gt;
#include &lt;boost/asio.hpp&gt;
#include &lt;boost/thread/thread.hpp&gt;
#include &lt;boost/bind/bind.hpp&gt;
class printer
{
public:
printer(boost::asio::io_context&amp; io)
: strand_(boost::asio::make_strand(io)),
timer1_(io, boost::asio::chrono::seconds(1)),
timer2_(io, boost::asio::chrono::seconds(1)),
count_(0)
{
timer1_.async_wait(boost::asio::bind_executor(strand_,
boost::bind(&amp;printer::print1, this)));
timer2_.async_wait(boost::asio::bind_executor(strand_,
boost::bind(&amp;printer::print2, this)));
}
~printer()
{
std::cout &lt;&lt; "Final count is " &lt;&lt; count_ &lt;&lt; std::endl;
}
void print1()
{
if (count_ &lt; 10)
{
std::cout &lt;&lt; "Timer 1: " &lt;&lt; count_ &lt;&lt; std::endl;
++count_;
timer1_.expires_at(timer1_.expiry() + boost::asio::chrono::seconds(1));
timer1_.async_wait(boost::asio::bind_executor(strand_,
boost::bind(&amp;printer::print1, this)));
}
}
void print2()
{
if (count_ &lt; 10)
{
std::cout &lt;&lt; "Timer 2: " &lt;&lt; count_ &lt;&lt; std::endl;
++count_;
timer2_.expires_at(timer2_.expiry() + boost::asio::chrono::seconds(1));
timer2_.async_wait(boost::asio::bind_executor(strand_,
boost::bind(&amp;printer::print2, this)));
}
}
private:
boost::asio::strand&lt;boost::asio::io_context::executor_type&gt; strand_;
boost::asio::steady_timer timer1_;
boost::asio::steady_timer timer2_;
int count_;
};
int main()
{
boost::asio::io_context io;
printer p(io);
boost::thread t(boost::bind(&amp;boost::asio::io_context::run, &amp;io));
io.run();
t.join();
return 0;
}
</pre>
<p>
Return to <a class="link" href="../tuttimer5.html" title="Timer.5 - Synchronising handlers in multithreaded programs">Timer.5 - Synchronising
handlers in multithreaded programs</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-2021 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="../tuttimer5.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tuttimer5.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../tutdaytime1.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>