1<html> 2<head> 3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 4<title>Daytime.3 - An asynchronous TCP daytime server</title> 5<link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css"> 6<meta name="generator" content="DocBook XSL Stylesheets V1.79.1"> 7<link rel="home" href="../../boost_asio.html" title="Boost.Asio"> 8<link rel="up" href="../tutorial.html" title="Tutorial"> 9<link rel="prev" href="tutdaytime2/src.html" title="Source listing for Daytime.2"> 10<link rel="next" href="tutdaytime3/src.html" title="Source listing for Daytime.3"> 11</head> 12<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> 13<table cellpadding="2" width="100%"><tr> 14<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../boost.png"></td> 15<td align="center"><a href="../../../../index.html">Home</a></td> 16<td align="center"><a href="../../../../libs/libraries.htm">Libraries</a></td> 17<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> 18<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> 19<td align="center"><a href="../../../../more/index.htm">More</a></td> 20</tr></table> 21<hr> 22<div class="spirit-nav"> 23<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> 24</div> 25<div class="section"> 26<div class="titlepage"><div><div><h3 class="title"> 27<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 28 TCP daytime server</a> 29</h3></div></div></div> 30<h5> 31<a name="boost_asio.tutorial.tutdaytime3.h0"></a> 32 <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 33 main() function</a> 34 </h5> 35<pre class="programlisting">int main() 36{ 37 try 38 { 39</pre> 40<p> 41 We need to create a server object to accept incoming client connections. 42 The <a class="link" href="../reference/io_context.html" title="io_context">io_context</a> object 43 provides I/O services, such as sockets, that the server object will use. 44 </p> 45<pre class="programlisting"> boost::asio::io_context io_context; 46 tcp_server server(io_context); 47</pre> 48<p> 49 Run the <a class="link" href="../reference/io_context.html" title="io_context">io_context</a> 50 object so that it will perform asynchronous operations on your behalf. 51 </p> 52<pre class="programlisting"> io_context.run(); 53 } 54 catch (std::exception& e) 55 { 56 std::cerr << e.what() << std::endl; 57 } 58 59 return 0; 60} 61</pre> 62<h5> 63<a name="boost_asio.tutorial.tutdaytime3.h1"></a> 64 <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 65 class</a> 66 </h5> 67<pre class="programlisting">class tcp_server 68{ 69public: 70</pre> 71<p> 72 The constructor initialises an acceptor to listen on TCP port 13. 73 </p> 74<pre class="programlisting"> tcp_server(boost::asio::io_context& io_context) 75 : io_context_(io_context), 76 acceptor_(io_context, tcp::endpoint(tcp::v4(), 13)) 77 { 78 start_accept(); 79 } 80 81private: 82</pre> 83<p> 84 The function <code class="computeroutput">start_accept()</code> creates a socket and initiates an 85 asynchronous accept operation to wait for a new connection. 86 </p> 87<pre class="programlisting"> void start_accept() 88 { 89 tcp_connection::pointer new_connection = 90 tcp_connection::create(io_context_); 91 92 acceptor_.async_accept(new_connection->socket(), 93 boost::bind(&tcp_server::handle_accept, this, new_connection, 94 boost::asio::placeholders::error)); 95 } 96</pre> 97<p> 98 The function <code class="computeroutput">handle_accept()</code> is called when the asynchronous 99 accept operation initiated by <code class="computeroutput">start_accept()</code> finishes. It services 100 the client request, and then calls <code class="computeroutput">start_accept()</code> to initiate 101 the next accept operation. 102 </p> 103<pre class="programlisting"> void handle_accept(tcp_connection::pointer new_connection, 104 const boost::system::error_code& error) 105 { 106 if (!error) 107 { 108 new_connection->start(); 109 } 110 111 start_accept(); 112 } 113</pre> 114<h5> 115<a name="boost_asio.tutorial.tutdaytime3.h2"></a> 116 <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 117 class</a> 118 </h5> 119<p> 120 We will use <code class="computeroutput">shared_ptr</code> and <code class="computeroutput">enable_shared_from_this</code> 121 because we want to keep the <code class="computeroutput">tcp_connection</code> object alive as long 122 as there is an operation that refers to it. 123 </p> 124<pre class="programlisting">class tcp_connection 125 : public boost::enable_shared_from_this<tcp_connection> 126{ 127public: 128 typedef boost::shared_ptr<tcp_connection> pointer; 129 130 static pointer create(boost::asio::io_context& io_context) 131 { 132 return pointer(new tcp_connection(io_context)); 133 } 134 135 tcp::socket& socket() 136 { 137 return socket_; 138 } 139</pre> 140<p> 141 In the function <code class="computeroutput">start()</code>, we call boost::asio::async_write() 142 to serve the data to the client. Note that we are using boost::asio::async_write(), 143 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>, 144 to ensure that the entire block of data is sent. 145 </p> 146<pre class="programlisting"> void start() 147 { 148</pre> 149<p> 150 The data to be sent is stored in the class member <code class="computeroutput">message_</code> as 151 we need to keep the data valid until the asynchronous operation is complete. 152 </p> 153<pre class="programlisting"> message_ = make_daytime_string(); 154</pre> 155<p> 156 When initiating the asynchronous operation, and if using boost::bind(), you 157 must specify only the arguments that match the handler's parameter list. 158 In this program, both of the argument placeholders (boost::asio::placeholders::error 159 and boost::asio::placeholders::bytes_transferred) could potentially have 160 been removed, since they are not being used in <code class="computeroutput">handle_write()</code>. 161 </p> 162<pre class="programlisting"> boost::asio::async_write(socket_, boost::asio::buffer(message_), 163 boost::bind(&tcp_connection::handle_write, shared_from_this(), 164 boost::asio::placeholders::error, 165 boost::asio::placeholders::bytes_transferred)); 166</pre> 167<p> 168 Any further actions for this client connection are now the responsibility 169 of <code class="computeroutput">handle_write()</code>. 170 </p> 171<pre class="programlisting"> } 172 173private: 174 tcp_connection(boost::asio::io_context& io_context) 175 : socket_(io_context) 176 { 177 } 178 179 void handle_write(const boost::system::error_code& /*error*/, 180 size_t /*bytes_transferred*/) 181 { 182 } 183 184 tcp::socket socket_; 185 std::string message_; 186}; 187</pre> 188<h5> 189<a name="boost_asio.tutorial.tutdaytime3.h3"></a> 190 <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 191 unused handler parameters</a> 192 </h5> 193<p> 194 You may have noticed that the <code class="computeroutput">error</code>, and <code class="computeroutput">bytes_transferred</code> 195 parameters are not used in the body of the <code class="computeroutput">handle_write()</code> function. 196 If parameters are not needed, it is possible to remove them from the function 197 so that it looks like: 198 </p> 199<pre class="programlisting"> void handle_write() 200 { 201 } 202</pre> 203<p> 204 The boost::asio::async_write() call used to initiate the call can then be 205 changed to just: 206 </p> 207<pre class="programlisting"> boost::asio::async_write(socket_, boost::asio::buffer(message_), 208 boost::bind(&tcp_connection::handle_write, shared_from_this())); 209</pre> 210<p> 211 See the <a class="link" href="tutdaytime3/src.html" title="Source listing for Daytime.3">full source listing</a> 212 </p> 213<p> 214 Return to the <a class="link" href="../tutorial.html" title="Tutorial">tutorial index</a> 215 </p> 216<p> 217 Previous: <a class="link" href="tutdaytime2.html" title="Daytime.2 - A synchronous TCP daytime server">Daytime.2 - A synchronous 218 TCP daytime server</a> 219 </p> 220<p> 221 Next: <a class="link" href="tutdaytime4.html" title="Daytime.4 - A synchronous UDP daytime client">Daytime.4 - A synchronous 222 UDP daytime client</a> 223 </p> 224</div> 225<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> 226<td align="left"></td> 227<td align="right"><div class="copyright-footer">Copyright © 2003-2020 Christopher M. 228 Kohlhoff<p> 229 Distributed under the Boost Software License, Version 1.0. (See accompanying 230 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>) 231 </p> 232</div></td> 233</tr></table> 234<hr> 235<div class="spirit-nav"> 236<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> 237</div> 238</body> 239</html> 240