1 //
2 // daytime_client.cpp
3 // ~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2015 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 
get_daytime(boost::asio::io_service & io_service,const char * hostname)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 
main(int argc,char * argv[])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 }
95