sender.cpp 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. //
  2. // sender.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 <iostream>
  11. #include <sstream>
  12. #include <string>
  13. #include <boost/asio.hpp>
  14. constexpr short multicast_port = 30001;
  15. constexpr int max_message_count = 10;
  16. class sender
  17. {
  18. public:
  19. sender(boost::asio::io_context& io_context,
  20. const boost::asio::ip::address& multicast_address)
  21. : endpoint_(multicast_address, multicast_port),
  22. socket_(io_context, endpoint_.protocol()),
  23. timer_(io_context),
  24. message_count_(0)
  25. {
  26. do_send();
  27. }
  28. private:
  29. void do_send()
  30. {
  31. std::ostringstream os;
  32. os << "Message " << message_count_++;
  33. message_ = os.str();
  34. socket_.async_send_to(
  35. boost::asio::buffer(message_), endpoint_,
  36. [this](boost::system::error_code ec, std::size_t /*length*/)
  37. {
  38. if (!ec && message_count_ < max_message_count)
  39. do_timeout();
  40. });
  41. }
  42. void do_timeout()
  43. {
  44. timer_.expires_after(std::chrono::seconds(1));
  45. timer_.async_wait(
  46. [this](boost::system::error_code ec)
  47. {
  48. if (!ec)
  49. do_send();
  50. });
  51. }
  52. private:
  53. boost::asio::ip::udp::endpoint endpoint_;
  54. boost::asio::ip::udp::socket socket_;
  55. boost::asio::steady_timer timer_;
  56. int message_count_;
  57. std::string message_;
  58. };
  59. int main(int argc, char* argv[])
  60. {
  61. try
  62. {
  63. if (argc != 2)
  64. {
  65. std::cerr << "Usage: sender <multicast_address>\n";
  66. std::cerr << " For IPv4, try:\n";
  67. std::cerr << " sender 239.255.0.1\n";
  68. std::cerr << " For IPv6, try:\n";
  69. std::cerr << " sender ff31::8000:1234\n";
  70. return 1;
  71. }
  72. boost::asio::io_context io_context;
  73. sender s(io_context, boost::asio::ip::make_address(argv[1]));
  74. io_context.run();
  75. }
  76. catch (std::exception& e)
  77. {
  78. std::cerr << "Exception: " << e.what() << "\n";
  79. }
  80. return 0;
  81. }