]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // |
2 | // daytime_client.cpp | |
3 | // ~~~~~~~~~~~~~~~~~~ | |
4 | // | |
5 | // Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com) | |
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> | |
15 | #include <boost/asio/io_service.hpp> | |
16 | #include <boost/asio/ip/udp.hpp> | |
17 | #include <boost/asio/use_future.hpp> | |
18 | ||
19 | using boost::asio::ip::udp; | |
20 | ||
21 | void get_daytime(boost::asio::io_service& io_service, const char* hostname) | |
22 | { | |
23 | try | |
24 | { | |
25 | udp::resolver resolver(io_service); | |
26 | ||
27 | std::future<udp::resolver::iterator> iter = | |
28 | resolver.async_resolve( | |
29 | {udp::v4(), hostname, "daytime"}, | |
30 | boost::asio::use_future); | |
31 | ||
32 | // The async_resolve operation above returns the endpoint iterator as a | |
33 | // future value that is not retrieved ... | |
34 | ||
35 | udp::socket socket(io_service, udp::v4()); | |
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), | |
40 | *iter.get(), // ... until here. This call may block. | |
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 | ||
77 | // We run the io_service off in its own thread so that it operates | |
78 | // completely asynchronously with respect to the rest of the program. | |
79 | boost::asio::io_service io_service; | |
80 | boost::asio::io_service::work work(io_service); | |
81 | std::thread thread([&io_service](){ io_service.run(); }); | |
82 | ||
83 | get_daytime(io_service, argv[1]); | |
84 | ||
85 | io_service.stop(); | |
86 | thread.join(); | |
87 | } | |
88 | catch (std::exception& e) | |
89 | { | |
90 | std::cerr << e.what() << std::endl; | |
91 | } | |
92 | ||
93 | return 0; | |
94 | } |