tutorial.qbk
来自「Boost provides free peer-reviewed portab」· QBK 代码 · 共 2,067 行 · 第 1/5 页
QBK
2,067 行
[/ / Copyright (c) 2003-2008 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) /][section:tutorial Tutorial][heading Basic Skills]The tutorial programs in this first section introduce the fundamental concepts required to use the asio toolkit. Before plunging into the complex world of network programming, these tutorial programs illustrate the basic skills using simple asynchronous timers.* [link boost_asio.tutorial.tuttimer1 Timer.1 - Using a timer synchronously]* [link boost_asio.tutorial.tuttimer2 Timer.2 - Using a timer asynchronously]* [link boost_asio.tutorial.tuttimer3 Timer.3 - Binding arguments to a handler]* [link boost_asio.tutorial.tuttimer4 Timer.4 - Using a member function as a handler]* [link boost_asio.tutorial.tuttimer5 Timer.5 - Synchronising handlers in multithreaded programs][heading Introduction to Sockets]The tutorial programs in this section show how to use asio to develop simple client and server programs. These tutorial programs are based around the [@http://www.ietf.org/rfc/rfc867.txt daytime] protocol, which supports both TCP and UDP.The first three tutorial programs implement the daytime protocol using TCP.* [link boost_asio.tutorial.tutdaytime1 Daytime.1 - A synchronous TCP daytime client]* [link boost_asio.tutorial.tutdaytime2 Daytime.2 - A synchronous TCP daytime server]* [link boost_asio.tutorial.tutdaytime3 Daytime.3 - An asynchronous TCP daytime server]The next three tutorial programs implement the daytime protocol using UDP.* [link boost_asio.tutorial.tutdaytime4 Daytime.4 - A synchronous UDP daytime client]* [link boost_asio.tutorial.tutdaytime5 Daytime.5 - A synchronous UDP daytime server]* [link boost_asio.tutorial.tutdaytime6 Daytime.6 - An asynchronous UDP daytime server]The last tutorial program in this section demonstrates how asio allows the TCP and UDP servers to be easily combined into a single program.* [link boost_asio.tutorial.tutdaytime7 Daytime.7 - A combined TCP/UDP asynchronous server][section:tuttimer1 Timer.1 - Using a timer synchronously]This tutorial program introduces asio by showing how to perform a blocking wait on a timer.We start by including the necessary header files.All of the asio classes can be used by simply including the `"asio.hpp"` header file. ``''''''``#include <iostream> ``''''''``#include <boost/asio.hpp>Since this example users timers, we need to include the appropriate Boost.Date\_Time header file for manipulating times. ``''''''``#include <boost/date_time/posix_time/posix_time.hpp>All programs that use asio need to have at least one [link boost_asio.reference.io_service io_service] object. This class provides access to I/O functionality. We declare an object of this type first thing in the main function. ``''''''``int main() ``''''''``{ ``''''''`` boost::asio::io_service io;Next we declare an object of type boost::asio::deadline\_timer. The core asio classes that provide I/O functionality (or as in this case timer functionality) always take a reference to an io\_service as their first constructor argument. The second argument to the constructor sets the timer to expire 5 seconds from now. ``''''''`` boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));In this simple example we perform a blocking wait on the timer. That is, the call to [link boost_asio.reference.basic_deadline_timer.wait deadline_timer::wait()] will not return until the timer has expired, 5 seconds after it was created (i.e. not from when the wait starts).A deadline timer is always in one of two states: "expired" or "not expired". If the [link boost_asio.reference.basic_deadline_timer.wait deadline_timer::wait()] function is called on an expired timer, it will return immediately. ``''''''`` t.wait();Finally we print the obligatory `"Hello, world!"` message to show when the timer has expired. ``''''''`` std::cout << "Hello, world!\n"; ``''''''`` return 0; ``''''''``}See the [link boost_asio.tutorial.tuttimer1.src full source listing]Return to the [link boost_asio.tutorial tutorial index]Next: [link boost_asio.tutorial.tuttimer2 Timer.2 - Using a timer asynchronously][section:src Source listing for Timer.1] ``''''''``// ``''''''``// timer.cpp ``''''''``// ~~~~~~~~~ ``''''''``// ``''''''``// Copyright (c) 2003-2008 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 <iostream> ``''''''``#include <boost/asio.hpp> ``''''''``#include <boost/date_time/posix_time/posix_time.hpp> ``''''''``int main() ``''''''``{ ``''''''`` boost::asio::io_service io; ``''''''`` boost::asio::deadline_timer t(io, boost::posix_time::seconds(5)); ``''''''`` t.wait(); ``''''''`` std::cout << "Hello, world!\n"; ``''''''`` return 0; ``''''''``}Return to [link boost_asio.tutorial.tuttimer1 Timer.1 - Using a timer synchronously][endsect][endsect][section:tuttimer2 Timer.2 - Using a timer asynchronously]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. ``''''''``#include <iostream> ``''''''``#include <boost/asio.hpp> ``''''''``#include <boost/date_time/posix_time/posix_time.hpp>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 `print` to be called when the asynchronous wait finishes. ``''''''``void print(const boost::system::error_code& /*e*/) ``''''''``{ ``''''''`` std::cout << "Hello, world!\n"; ``''''''``} ``''''''``int main() ``''''''``{ ``''''''`` boost::asio::io_service io; ``''''''`` boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));Next, instead of doing a blocking wait as in tutorial Timer.1, we call the [link boost_asio.reference.basic_deadline_timer.async_wait deadline_timer::async_wait()] function to perform an asynchronous wait. When calling this function we pass the `print` callback handler that was defined above. ``''''''`` t.async_wait(print);Finally, we must call the [link boost_asio.reference.io_service.run io_service::run()] member function on the io\_service object.The asio library provides a guarantee that callback handlers will only be called from threads that are currently calling [link boost_asio.reference.io_service.run io_service::run()]. Therefore unless the [link boost_asio.reference.io_service.run io_service::run()] function is called the callback for the asynchronous wait completion will never be invoked.The [link boost_asio.reference.io_service.run io_service::run()] 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.It is important to remember to give the io\_service some work to do before calling [link boost_asio.reference.io_service.run io_service::run()]. For example, if we had omitted the above call to [link boost_asio.reference.basic_deadline_timer.async_wait deadline_timer::async_wait()], the io\_service would not have had any work to do, and consequently [link boost_asio.reference.io_service.run io_service::run()] would have returned immediately. ``''''''`` io.run(); ``''''''`` return 0; ``''''''``}See the [link boost_asio.tutorial.tuttimer2.src full source listing]Return to the [link boost_asio.tutorial tutorial index]Previous: [link boost_asio.tutorial.tuttimer1 Timer.1 - Using a timer synchronously]Next: [link boost_asio.tutorial.tuttimer3 Timer.3 - Binding arguments to a handler][section:src Source listing for Timer.2] ``''''''``// ``''''''``// timer.cpp ``''''''``// ~~~~~~~~~ ``''''''``// ``''''''``// Copyright (c) 2003-2008 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 <iostream> ``''''''``#include <boost/asio.hpp> ``''''''``#include <boost/date_time/posix_time/posix_time.hpp> ``''''''``void print(const boost::system::error_code& /*e*/) ``''''''``{ ``''''''`` std::cout << "Hello, world!\n"; ``''''''``} ``''''''``int main() ``''''''``{ ``''''''`` boost::asio::io_service io; ``''''''`` boost::asio::deadline_timer t(io, boost::posix_time::seconds(5)); ``''''''`` t.async_wait(print); ``''''''`` io.run(); ``''''''`` return 0; ``''''''``}Return to [link boost_asio.tutorial.tuttimer2 Timer.2 - Using a timer asynchronously][endsect][endsect][section:tuttimer3 Timer.3 - Binding arguments to a handler]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. ``''''''``#include <iostream> ``''''''``#include <boost/asio.hpp> ``''''''``#include <boost/bind.hpp> ``''''''``#include <boost/date_time/posix_time/posix_time.hpp>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 `print` function:* A pointer to a timer object.* A counter so that we can stop the program when the timer fires for the sixth time. ``''''''``void print(const boost::system::error_code& /*e*/, ``''''''`` boost::asio::deadline_timer* t, int* count) ``''''''``{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\_service to stop. Recall that in tutorial Timer.2 we learnt that the [link boost_asio.reference.io_service.run io_service::run()] function completes when there is no more "work" to do. By not starting a new asynchronous wait on the timer when `count` reaches 5, the io\_service will run out of work and stop running. ``''''''`` if (*count < 5) ``''''''`` { ``''''''`` std::cout << *count << "\n"; ``''''''`` ++(*count);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. ``''''''`` t->expires_at(t->expires_at() + boost::posix_time::seconds(1));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 [link boost_asio.reference.basic_deadline_timer.async_wait deadline_timer::async_wait()] function expects a handler function (or function object) with the signature `void(const boost::system::error_code&)`. Binding the additional parameters converts your `print` function into a function object that matches the signature correctly.See the [@http://www.boost.org/libs/bind/bind.html Boost.Bind documentation] for more information on how to use boost::bind().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. ``''''''`` t->async_wait(boost::bind(print, ``''''''`` boost::asio::placeholders::error, t, count)); ``''''''`` } ``''''''``} ``''''''``int main() ``''''''``{ ``''''''`` boost::asio::io_service io;A new `count` variable is added so that we can stop the program when the timer fires for the sixth time. ``''''''`` int count = 0; ``''''''`` boost::asio::deadline_timer t(io, boost::posix_time::seconds(1));As in Step 4, when making the call to [link boost_asio.reference.basic_deadline_timer.async_wait deadline_timer::async_wait()] from `main` we bind the additional parameters needed for the `print` function. ``''''''`` t.async_wait(boost::bind(print, ``''''''`` boost::asio::placeholders::error, &t, &count)); ``''''''`` io.run();Finally, just to prove that the `count` variable was being used in the `print` handler function, we will print out its new value. ``''''''`` std::cout << "Final count is " << count << "\n"; ``''''''`` return 0; ``''''''``}See the [link boost_asio.tutorial.tuttimer3.src full source listing]Return to the [link boost_asio.tutorial tutorial index]Previous: [link boost_asio.tutorial.tuttimer2 Timer.2 - Using a timer asynchronously]Next: [link boost_asio.tutorial.tuttimer4 Timer.4 - Using a member function as a handler][section:src Source listing for Timer.3] ``''''''``// ``''''''``// timer.cpp ``''''''``// ~~~~~~~~~ ``''''''``// ``''''''``// Copyright (c) 2003-2008 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 <iostream> ``''''''``#include <boost/asio.hpp> ``''''''``#include <boost/bind.hpp> ``''''''``#include <boost/date_time/posix_time/posix_time.hpp> ``''''''``void print(const boost::system::error_code& /*e*/, ``''''''`` boost::asio::deadline_timer* t, int* count) ``''''''``{ ``''''''`` if (*count < 5) ``''''''`` { ``''''''`` std::cout << *count << "\n"; ``''''''`` ++(*count); ``''''''`` t->expires_at(t->expires_at() + boost::posix_time::seconds(1)); ``''''''`` t->async_wait(boost::bind(print, ``''''''`` boost::asio::placeholders::error, t, count));
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?