]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // |
2 | // daytime_client.cpp | |
3 | // ~~~~~~~~~~~~~~~~~~ | |
4 | // | |
92f5a8d4 | 5 | // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) |
7c673cae FG |
6 | // |
7 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
8 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
9 | // | |
10 | ||
11 | #include <array> | |
12 | #include <future> | |
13 | #include <iostream> | |
14 | #include <thread> | |
b32b8144 | 15 | #include <boost/asio/io_context.hpp> |
7c673cae FG |
16 | #include <boost/asio/ip/udp.hpp> |
17 | #include <boost/asio/use_future.hpp> | |
18 | ||
19 | using boost::asio::ip::udp; | |
20 | ||
b32b8144 | 21 | void get_daytime(boost::asio::io_context& io_context, const char* hostname) |
7c673cae FG |
22 | { |
23 | try | |
24 | { | |
b32b8144 | 25 | udp::resolver resolver(io_context); |
7c673cae | 26 | |
b32b8144 | 27 | std::future<udp::resolver::results_type> endpoints = |
7c673cae | 28 | resolver.async_resolve( |
b32b8144 | 29 | udp::v4(), hostname, "daytime", |
7c673cae FG |
30 | boost::asio::use_future); |
31 | ||
b32b8144 FG |
32 | // The async_resolve operation above returns the endpoints as a future |
33 | // value that is not retrieved ... | |
7c673cae | 34 | |
b32b8144 | 35 | udp::socket socket(io_context, udp::v4()); |
7c673cae FG |
36 | |
37 | std::array<char, 1> send_buf = {{ 0 }}; | |
38 | std::future<std::size_t> send_length = | |
39 | socket.async_send_to(boost::asio::buffer(send_buf), | |
b32b8144 | 40 | *endpoints.get().begin(), // ... until here. This call may block. |
7c673cae FG |
41 | boost::asio::use_future); |
42 | ||
43 | // Do other things here while the send completes. | |
44 | ||
45 | send_length.get(); // Blocks until the send is complete. Throws any errors. | |
46 | ||
47 | std::array<char, 128> recv_buf; | |
48 | udp::endpoint sender_endpoint; | |
49 | std::future<std::size_t> recv_length = | |
50 | socket.async_receive_from( | |
51 | boost::asio::buffer(recv_buf), | |
52 | sender_endpoint, | |
53 | boost::asio::use_future); | |
54 | ||
55 | // Do other things here while the receive completes. | |
56 | ||
57 | std::cout.write( | |
58 | recv_buf.data(), | |
59 | recv_length.get()); // Blocks until receive is complete. | |
60 | } | |
61 | catch (std::system_error& e) | |
62 | { | |
63 | std::cerr << e.what() << std::endl; | |
64 | } | |
65 | } | |
66 | ||
67 | int main(int argc, char* argv[]) | |
68 | { | |
69 | try | |
70 | { | |
71 | if (argc != 2) | |
72 | { | |
73 | std::cerr << "Usage: daytime_client <host>" << std::endl; | |
74 | return 1; | |
75 | } | |
76 | ||
b32b8144 | 77 | // We run the io_context off in its own thread so that it operates |
7c673cae | 78 | // completely asynchronously with respect to the rest of the program. |
b32b8144 FG |
79 | boost::asio::io_context io_context; |
80 | auto work = boost::asio::make_work_guard(io_context); | |
81 | std::thread thread([&io_context](){ io_context.run(); }); | |
7c673cae | 82 | |
b32b8144 | 83 | get_daytime(io_context, argv[1]); |
7c673cae | 84 | |
b32b8144 | 85 | io_context.stop(); |
7c673cae FG |
86 | thread.join(); |
87 | } | |
88 | catch (std::exception& e) | |
89 | { | |
90 | std::cerr << e.what() << std::endl; | |
91 | } | |
92 | ||
93 | return 0; | |
94 | } |