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