daytime_client.cpp 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. //
  2. // daytime_client.cpp
  3. // ~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2019 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. #include <array>
  11. #include <future>
  12. #include <iostream>
  13. #include <thread>
  14. #include <boost/asio/io_context.hpp>
  15. #include <boost/asio/ip/udp.hpp>
  16. #include <boost/asio/use_future.hpp>
  17. using boost::asio::ip::udp;
  18. void get_daytime(boost::asio::io_context& io_context, const char* hostname)
  19. {
  20. try
  21. {
  22. udp::resolver resolver(io_context);
  23. std::future<udp::resolver::results_type> endpoints =
  24. resolver.async_resolve(
  25. udp::v4(), hostname, "daytime",
  26. boost::asio::use_future);
  27. // The async_resolve operation above returns the endpoints as a future
  28. // value that is not retrieved ...
  29. udp::socket socket(io_context, udp::v4());
  30. std::array<char, 1> send_buf = {{ 0 }};
  31. std::future<std::size_t> send_length =
  32. socket.async_send_to(boost::asio::buffer(send_buf),
  33. *endpoints.get().begin(), // ... until here. This call may block.
  34. boost::asio::use_future);
  35. // Do other things here while the send completes.
  36. send_length.get(); // Blocks until the send is complete. Throws any errors.
  37. std::array<char, 128> recv_buf;
  38. udp::endpoint sender_endpoint;
  39. std::future<std::size_t> recv_length =
  40. socket.async_receive_from(
  41. boost::asio::buffer(recv_buf),
  42. sender_endpoint,
  43. boost::asio::use_future);
  44. // Do other things here while the receive completes.
  45. std::cout.write(
  46. recv_buf.data(),
  47. recv_length.get()); // Blocks until receive is complete.
  48. }
  49. catch (std::system_error& e)
  50. {
  51. std::cerr << e.what() << std::endl;
  52. }
  53. }
  54. int main(int argc, char* argv[])
  55. {
  56. try
  57. {
  58. if (argc != 2)
  59. {
  60. std::cerr << "Usage: daytime_client <host>" << std::endl;
  61. return 1;
  62. }
  63. // We run the io_context off in its own thread so that it operates
  64. // completely asynchronously with respect to the rest of the program.
  65. boost::asio::io_context io_context;
  66. auto work = boost::asio::make_work_guard(io_context);
  67. std::thread thread([&io_context](){ io_context.run(); });
  68. get_daytime(io_context, argv[1]);
  69. io_context.stop();
  70. thread.join();
  71. }
  72. catch (std::exception& e)
  73. {
  74. std::cerr << e.what() << std::endl;
  75. }
  76. return 0;
  77. }