• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // sender.cpp
3 // ~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2020 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 <iostream>
12 #include <sstream>
13 #include <string>
14 #include <boost/asio.hpp>
15 #include "boost/bind/bind.hpp"
16 
17 const short multicast_port = 30001;
18 const int max_message_count = 10;
19 
20 class sender
21 {
22 public:
sender(boost::asio::io_context & io_context,const boost::asio::ip::address & multicast_address)23   sender(boost::asio::io_context& io_context,
24       const boost::asio::ip::address& multicast_address)
25     : endpoint_(multicast_address, multicast_port),
26       socket_(io_context, endpoint_.protocol()),
27       timer_(io_context),
28       message_count_(0)
29   {
30     std::ostringstream os;
31     os << "Message " << message_count_++;
32     message_ = os.str();
33 
34     socket_.async_send_to(
35         boost::asio::buffer(message_), endpoint_,
36         boost::bind(&sender::handle_send_to, this,
37           boost::asio::placeholders::error));
38   }
39 
handle_send_to(const boost::system::error_code & error)40   void handle_send_to(const boost::system::error_code& error)
41   {
42     if (!error && message_count_ < max_message_count)
43     {
44       timer_.expires_after(boost::asio::chrono::seconds(1));
45       timer_.async_wait(
46           boost::bind(&sender::handle_timeout, this,
47             boost::asio::placeholders::error));
48     }
49   }
50 
handle_timeout(const boost::system::error_code & error)51   void handle_timeout(const boost::system::error_code& error)
52   {
53     if (!error)
54     {
55       std::ostringstream os;
56       os << "Message " << message_count_++;
57       message_ = os.str();
58 
59       socket_.async_send_to(
60           boost::asio::buffer(message_), endpoint_,
61           boost::bind(&sender::handle_send_to, this,
62             boost::asio::placeholders::error));
63     }
64   }
65 
66 private:
67   boost::asio::ip::udp::endpoint endpoint_;
68   boost::asio::ip::udp::socket socket_;
69   boost::asio::steady_timer timer_;
70   int message_count_;
71   std::string message_;
72 };
73 
main(int argc,char * argv[])74 int main(int argc, char* argv[])
75 {
76   try
77   {
78     if (argc != 2)
79     {
80       std::cerr << "Usage: sender <multicast_address>\n";
81       std::cerr << "  For IPv4, try:\n";
82       std::cerr << "    sender 239.255.0.1\n";
83       std::cerr << "  For IPv6, try:\n";
84       std::cerr << "    sender ff31::8000:1234\n";
85       return 1;
86     }
87 
88     boost::asio::io_context io_context;
89     sender s(io_context, boost::asio::ip::make_address(argv[1]));
90     io_context.run();
91   }
92   catch (std::exception& e)
93   {
94     std::cerr << "Exception: " << e.what() << "\n";
95   }
96 
97   return 0;
98 }
99