//
// Copyright (c) 2003-2010 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)
//

/**
\page tutdaytime1 Daytime.1 - A synchronous TCP daytime client

This tutorial program shows how to use asio to implement a client application
with TCP.

\dontinclude daytime1/client.cpp
\skip #include

We start by including the necessary header files.

\until asio.hpp

The purpose of this application is to access a daytime service,
so we need the user to specify the server.

\until }

All programs that use asio need to have at least one boost::asio::io_service
object.

\until boost::asio::io_service

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
boost::asio::ip::tcp::resolver object.

\until tcp::resolver

A resolver takes a query object and turns it into a list of endpoints. We
construct a query using the name of the server, specified in <tt>argv[1]</tt>,
and the name of the service, in this case <tt>"daytime"</tt>.

\until tcp::resolver::query

The list of endpoints is returned using an iterator of type
boost::asio::ip::tcp::resolver::iterator. A default constructed
boost::asio::ip::tcp::resolver::iterator object is used as the end iterator.

\until tcp::resolver::iterator end;

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.

\until throw

The connection is open. All we need to do now is read the response from the
daytime service.

We use a <tt>boost::array</tt> 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 <tt>boost::array</tt>, we could have used a <tt>char
[]</tt> or <tt>std::vector</tt>.

\until read_some

When the server closes the connection, the boost::asio::ip::tcp::socket::read_some()
function will exit with the boost::asio::error::eof error, which is how we know to
exit the loop.

\until }

Finally, handle any exceptions that may have been thrown.

\until }
\until }

See the \ref tutdaytime1src "full source listing" \n
Return to the \ref index "tutorial index" \n
Next: \ref tutdaytime2

*/

/**
\page tutdaytime1src Source listing for Daytime.1
\include daytime1/client.cpp
Return to \ref tutdaytime1
*/

/**
\page tutdaytime2 Daytime.2 - A synchronous TCP daytime server

This tutorial program shows how to use asio to implement a server application
with TCP.

\dontinclude daytime2/server.cpp
\skip #include

\until using

We define the function <tt>make_daytime_string()</tt> to create the string to
be sent back to the client. This function will be reused in all of our daytime
server applications.

\until boost::asio::io_service

A boost::asio::ip::tcp::acceptor object needs to be created to listen
for new connections. It is initialised to listen on TCP port 13, for IP version 4.

\until tcp::acceptor

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.

\until acceptor.accept

A client is accessing our service. Determine the current time
and transfer this information to the client. 

\until }
\until }

Finally, handle any exceptions.

\until }
\until }

See the \ref tutdaytime2src "full source listing" \n
Return to the \ref index "tutorial index" \n
Previous: \ref tutdaytime1 \n
Next: \ref tutdaytime3

*/

/**
\page tutdaytime2src Source listing for Daytime.2
\include daytime2/server.cpp
Return to \ref tutdaytime2
*/

/**
\page tutdaytime3 Daytime.3 - An asynchronous TCP daytime server

\section tutdaytime3funcmain The main() function

\dontinclude daytime3/server.cpp
\skip int main()
\until try
\until {

We need to create a server object to accept incoming client connections. The
boost::asio::io_service object provides I/O services, such as sockets, that the
server object will use.

\until tcp_server

Run the boost::asio::io_service object so that it will perform asynchronous operations
on your behalf.

\until return 0;
\until }

\section tutdaytime3classtcp_server The tcp_server class

\dontinclude daytime3/server.cpp
\skip class tcp_server
\until public:

The constructor initialises an acceptor to listen on TCP port 13.

\until private:

The function <tt>start_accept()</tt> creates a socket and initiates an
asynchronous accept operation to wait for a new connection.

\until }

The function <tt>handle_accept()</tt> is called when the asynchronous accept
operation initiated by <tt>start_accept()</tt> finishes. It services the client
request, and then calls <tt>start_accept()</tt> to initiate the next accept
operation.

\until }
\until }

\section tutdaytime3classtcp_connection The tcp_connection class

We will use <tt>shared_ptr</tt> and <tt>enable_shared_from_this</tt> because we
want to keep the <tt>tcp_connection</tt> object alive as long as there is an
operation that refers to it.

\dontinclude daytime3/server.cpp
\skip class tcp_connection
\until shared_ptr
\until }
\until }

In the function <tt>start()</tt>, we call boost::asio::async_write() to serve the data
to the client. Note that we are using boost::asio::async_write(), rather than
boost::asio::ip::tcp::socket::async_write_some(), to ensure that the entire block of
data is sent.

\until {

The data to be sent is stored in the class member <tt>message_</tt> as we need
to keep the data valid until the asynchronous operation is complete.

\until message_

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 <tt>handle_write()</tt>.

\until placeholders::bytes_transferred

Any further actions for this client connection are now the responsibility of
<tt>handle_write()</tt>.

\until };

\section tutdaytime3remunused Removing unused handler parameters

You may have noticed that the <tt>error</tt>, and <tt>bytes_transferred</tt>
parameters are not used in the body of the <tt>handle_write()</tt> function. If
parameters are not needed, it is possible to remove them from the function so
that it looks like:

\code
  void handle_write()
  {
  }
\endcode

The boost::asio::async_write() call used to initiate the call can then be changed to
just:

\code
  boost::asio::async_write(socket_, boost::asio::buffer(message_),
      boost::bind(&tcp_connection::handle_write, shared_from_this()));
\endcode

See the \ref tutdaytime3src "full source listing" \n
Return to the \ref index "tutorial index" \n
Previous: \ref tutdaytime2 \n
Next: \ref tutdaytime4

*/

/**
\page tutdaytime3src Source listing for Daytime.3
\include daytime3/server.cpp
Return to \ref tutdaytime3
*/

/**
\page tutdaytime4 Daytime.4 - A synchronous UDP daytime client

This tutorial program shows how to use asio to implement a client application
with UDP.

\dontinclude daytime4/client.cpp
\skip #include
\until using boost::asio::ip::udp;

The start of the application is essentially the same as for the TCP daytime
client.

\until boost::asio::io_service

We use an boost::asio::ip::udp::resolver 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 boost::asio::ip::udp::v4() argument.

\until udp::v4

The boost::asio::ip::udp::resolver::resolve() 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.

\until udp::endpoint

Since UDP is datagram-oriented, we will not be using a stream socket. Create an
boost::asio::ip::udp::socket and initiate contact with the remote endpoint.

\until receiver_endpoint

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
boost::asio::ip::udp::socket::receive_from(). 

\until }

Finally, handle any exceptions that may have been thrown.

\until }
\until }
See the \ref tutdaytime4src "full source listing" \n
Return to the \ref index "tutorial index" \n
Previous: \ref tutdaytime3 \n
Next: \ref tutdaytime5

*/

/**
\page tutdaytime4src Source listing for Daytime.4
\include daytime4/client.cpp
Return to \ref tutdaytime4
*/

/**
\page tutdaytime5 Daytime.5 - A synchronous UDP daytime server

This tutorial program shows how to use asio to implement a server application
with UDP.

\dontinclude daytime5/server.cpp
\skip int main()
\until boost::asio::io_service

Create an boost::asio::ip::udp::socket object to receive requests on UDP port 13.

\until udp::socket

Wait for a client to initiate contact with us. The remote_endpoint object will
be populated by boost::asio::ip::udp::socket::receive_from().

\until throw

Determine what we are going to send back to the client.

\until std::string message

Send the response to the remote_endpoint.

\until }
\until }

Finally, handle any exceptions.

\until }
\until }

See the \ref tutdaytime5src "full source listing" \n
Return to the \ref index "tutorial index" \n
Previous: \ref tutdaytime4 \n
Next: \ref tutdaytime6

*/

/**
\page tutdaytime5src Source listing for Daytime.5
\include daytime5/server.cpp
Return to \ref tutdaytime5
*/

/**
\page tutdaytime6 Daytime.6 - An asynchronous UDP daytime server

\section tutdaytime6funcmain The main() function

\dontinclude daytime6/server.cpp
\skip int main()
\until try
\until {

Create a server object to accept incoming client requests, and run
the boost::asio::io_service object.

\until return 0;
\until }

\section tutdaytime6classudp_server The udp_server class

\dontinclude daytime6/server.cpp
\skip class udp_server
\until public:

The constructor initialises a socket to listen on UDP port 13.

\until private:
\until {

The function boost::asio::ip::udp::socket::async_receive_from() will cause the
application to listen in the background for a new request. When such a request
is received, the boost::asio::io_service object will invoke the
<tt>handle_receive()</tt> function with two arguments: a value of type
boost::system::error_code indicating whether the operation succeeded or failed, and a
<tt>size_t</tt> value <tt>bytes_transferred</tt> specifying the number of bytes
received.

\until }

The function <tt>handle_receive()</tt> will service the client request.

\until {

The <tt>error</tt> parameter contains the result of the asynchronous operation.
Since we only provide the 1-byte <tt>recv_buffer_</tt> to contain the client's
request, the boost::asio::io_service object would return an error if the client sent
anything larger. We can ignore such an error if it comes up.

\until {

Determine what we are going to send.

\until make_daytime_string()

We now call boost::asio::ip::udp::socket::async_send_to() to serve the data to the
client.

\until boost::asio::placeholders::bytes_transferred

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.

Start listening for the next client request.

\until start_receive

Any further actions for this client request are now the responsibility of
<tt>handle_send()</tt>.

\until }
\until }

The function <tt>handle_send()</tt> is invoked after the service request has
been completed.

\until }
\until }

See the \ref tutdaytime6src "full source listing" \n
Return to the \ref index "tutorial index" \n
Previous: \ref tutdaytime5 \n
Next: \ref tutdaytime7

*/

/**
\page tutdaytime6src Source listing for Daytime.6
\include daytime6/server.cpp
Return to \ref tutdaytime6
*/

/**
\page tutdaytime7 Daytime.7 - A combined TCP/UDP asynchronous server

This tutorial program shows how to combine the two asynchronous servers that we
have just written, into a single server application.

\section tutdaytime7funcmain The main() function

\dontinclude daytime7/server.cpp
\skip int main()
\until boost::asio::io_service

We will begin by creating a server object to accept a TCP client connection.

\until tcp_server

We also need a server object to accept a UDP client request.

\until udp_server

We have created two lots of work for the boost::asio::io_service object to do.

\until return 0;
\until }

\section tutdaytime7classtcp The tcp_connection and tcp_server classes

The following two classes are taken from \ref tutdaytime3 "Daytime.3".

\dontinclude daytime7/server.cpp
\skip class tcp_connection
\until };
\until };

\section tutdaytime7classudp The udp_server class

Similarly, this next class is taken from the
\ref tutdaytime6 "previous tutorial step".

\dontinclude daytime7/server.cpp
\skip class udp_server
\until };

See the \ref tutdaytime7src "full source listing" \n
Return to the \ref index "tutorial index" \n
Previous: \ref tutdaytime6

*/

/**
\page tutdaytime7src Source listing for Daytime.7
\include daytime7/server.cpp
Return to \ref tutdaytime7
*/
