receiver.cpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. //
  2. // receiver.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 <string>
  12. #include <boost/asio.hpp>
  13. #include "boost/bind.hpp"
  14. const short multicast_port = 30001;
  15. class receiver
  16. {
  17. public:
  18. receiver(boost::asio::io_context& io_context,
  19. const boost::asio::ip::address& listen_address,
  20. const boost::asio::ip::address& multicast_address)
  21. : socket_(io_context)
  22. {
  23. // Create the socket so that multiple may be bound to the same address.
  24. boost::asio::ip::udp::endpoint listen_endpoint(
  25. listen_address, multicast_port);
  26. socket_.open(listen_endpoint.protocol());
  27. socket_.set_option(boost::asio::ip::udp::socket::reuse_address(true));
  28. socket_.bind(listen_endpoint);
  29. // Join the multicast group.
  30. socket_.set_option(
  31. boost::asio::ip::multicast::join_group(multicast_address));
  32. socket_.async_receive_from(
  33. boost::asio::buffer(data_, max_length), sender_endpoint_,
  34. boost::bind(&receiver::handle_receive_from, this,
  35. boost::asio::placeholders::error,
  36. boost::asio::placeholders::bytes_transferred));
  37. }
  38. void handle_receive_from(const boost::system::error_code& error,
  39. size_t bytes_recvd)
  40. {
  41. if (!error)
  42. {
  43. std::cout.write(data_, bytes_recvd);
  44. std::cout << std::endl;
  45. socket_.async_receive_from(
  46. boost::asio::buffer(data_, max_length), sender_endpoint_,
  47. boost::bind(&receiver::handle_receive_from, this,
  48. boost::asio::placeholders::error,
  49. boost::asio::placeholders::bytes_transferred));
  50. }
  51. }
  52. private:
  53. boost::asio::ip::udp::socket socket_;
  54. boost::asio::ip::udp::endpoint sender_endpoint_;
  55. enum { max_length = 1024 };
  56. char data_[max_length];
  57. };
  58. int main(int argc, char* argv[])
  59. {
  60. try
  61. {
  62. if (argc != 3)
  63. {
  64. std::cerr << "Usage: receiver <listen_address> <multicast_address>\n";
  65. std::cerr << " For IPv4, try:\n";
  66. std::cerr << " receiver 0.0.0.0 239.255.0.1\n";
  67. std::cerr << " For IPv6, try:\n";
  68. std::cerr << " receiver 0::0 ff31::8000:1234\n";
  69. return 1;
  70. }
  71. boost::asio::io_context io_context;
  72. receiver r(io_context,
  73. boost::asio::ip::make_address(argv[1]),
  74. boost::asio::ip::make_address(argv[2]));
  75. io_context.run();
  76. }
  77. catch (std::exception& e)
  78. {
  79. std::cerr << "Exception: " << e.what() << "\n";
  80. }
  81. return 0;
  82. }