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