]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | [/ |
2 | / Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com) | |
3 | / | |
4 | / Distributed under the Boost Software License, Version 1.0. (See accompanying | |
5 | / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
6 | /] | |
7 | ||
8 | [section:basics Basic Boost.Asio Anatomy] | |
9 | ||
10 | Boost.Asio may be used to perform both synchronous and asynchronous operations on I/O | |
11 | objects such as sockets. Before using Boost.Asio it may be useful to get a conceptual | |
12 | picture of the various parts of Boost.Asio, your program, and how they work together. | |
13 | ||
14 | As an introductory example, let's consider what happens when you perform a | |
15 | connect operation on a socket. We shall start by examining synchronous | |
16 | operations. | |
17 | ||
18 | [$boost_asio/sync_op.png] | |
19 | ||
20 | [*Your program] will have at least one [*io_service] object. The [*io_service] | |
21 | represents [*your program]'s link to the [*operating system]'s I/O services. | |
22 | ||
23 | boost::asio::io_service io_service; | |
24 | ||
25 | To perform I/O operations [*your program] will need an [*I/O object] such as a | |
26 | TCP socket: | |
27 | ||
28 | boost::asio::ip::tcp::socket socket(io_service); | |
29 | ||
30 | When a synchronous connect operation is performed, the following sequence of | |
31 | events occurs: | |
32 | ||
33 | 1. [*Your program] initiates the connect operation by calling the [*I/O | |
34 | object]: | |
35 | ||
36 | socket.connect(server_endpoint); | |
37 | ||
38 | 2. The [*I/O object] forwards the request to the [*io_service]. | |
39 | ||
40 | 3. The [*io_service] calls on the [*operating system] to perform the connect | |
41 | operation. | |
42 | ||
43 | 4. The [*operating system] returns the result of the operation to the | |
44 | [*io_service]. | |
45 | ||
46 | 5. The [*io_service] translates any error resulting from the operation into an | |
47 | object of type `boost::system::error_code`. An `error_code` may be compared with | |
48 | specific values, or tested as a boolean (where a `false` result means that no | |
49 | error occurred). The result is then forwarded back up to the [*I/O object]. | |
50 | ||
51 | 6. The [*I/O object] throws an exception of type `boost::system::system_error` if the | |
52 | operation failed. If the code to initiate the operation had instead been | |
53 | written as: | |
54 | ||
55 | boost::system::error_code ec; | |
56 | socket.connect(server_endpoint, ec); | |
57 | ||
58 | then the `error_code` variable `ec` would be set to the result of the | |
59 | operation, and no exception would be thrown. | |
60 | ||
61 | When an asynchronous operation is used, a different sequence of events occurs. | |
62 | ||
63 | [$boost_asio/async_op1.png] | |
64 | ||
65 | 1. [*Your program] initiates the connect operation by calling the [*I/O | |
66 | object]: | |
67 | ||
68 | socket.async_connect(server_endpoint, your_completion_handler); | |
69 | ||
70 | where `your_completion_handler` is a function or function object with the | |
71 | signature: | |
72 | ||
73 | void your_completion_handler(const boost::system::error_code& ec); | |
74 | ||
75 | The exact signature required depends on the asynchronous operation being | |
76 | performed. The reference documentation indicates the appropriate form for each | |
77 | operation. | |
78 | ||
79 | 2. The [*I/O object] forwards the request to the [*io_service]. | |
80 | ||
81 | 3. The [*io_service] signals to the [*operating system] that it should start an | |
82 | asynchronous connect. | |
83 | ||
84 | Time passes. (In the synchronous case this wait would have been contained | |
85 | entirely within the duration of the connect operation.) | |
86 | ||
87 | [$boost_asio/async_op2.png] | |
88 | ||
89 | 4. The [*operating system] indicates that the connect operation has completed | |
90 | by placing the result on a queue, ready to be picked up by the [*io_service]. | |
91 | ||
92 | 5. [*Your program] must make a call to `io_service::run()` (or to one of the | |
93 | similar [*io_service] member functions) in order for the result to be | |
94 | retrieved. A call to `io_service::run()` blocks while there are unfinished | |
95 | asynchronous operations, so you would typically call it as soon as you have | |
96 | started your first asynchronous operation. | |
97 | ||
98 | 6. While inside the call to `io_service::run()`, the [*io_service] dequeues the | |
99 | result of the operation, translates it into an `error_code`, and then passes it | |
100 | to [*your completion handler]. | |
101 | ||
102 | This is a simplified picture of how Boost.Asio operates. You will want to delve | |
103 | further into the documentation if your needs are more advanced, such as | |
104 | extending Boost.Asio to perform other types of asynchronous operations. | |
105 | ||
106 | [endsect] |