async_udp_echo_server.cpp 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. //
  2. // async_udp_echo_server.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 <cstdlib>
  11. #include <iostream>
  12. #include <boost/bind.hpp>
  13. #include <boost/asio.hpp>
  14. using boost::asio::ip::udp;
  15. class server
  16. {
  17. public:
  18. server(boost::asio::io_context& io_context, short port)
  19. : socket_(io_context, udp::endpoint(udp::v4(), port))
  20. {
  21. socket_.async_receive_from(
  22. boost::asio::buffer(data_, max_length), sender_endpoint_,
  23. boost::bind(&server::handle_receive_from, this,
  24. boost::asio::placeholders::error,
  25. boost::asio::placeholders::bytes_transferred));
  26. }
  27. void handle_receive_from(const boost::system::error_code& error,
  28. size_t bytes_recvd)
  29. {
  30. if (!error && bytes_recvd > 0)
  31. {
  32. socket_.async_send_to(
  33. boost::asio::buffer(data_, bytes_recvd), sender_endpoint_,
  34. boost::bind(&server::handle_send_to, this,
  35. boost::asio::placeholders::error,
  36. boost::asio::placeholders::bytes_transferred));
  37. }
  38. else
  39. {
  40. socket_.async_receive_from(
  41. boost::asio::buffer(data_, max_length), sender_endpoint_,
  42. boost::bind(&server::handle_receive_from, this,
  43. boost::asio::placeholders::error,
  44. boost::asio::placeholders::bytes_transferred));
  45. }
  46. }
  47. void handle_send_to(const boost::system::error_code& /*error*/,
  48. size_t /*bytes_sent*/)
  49. {
  50. socket_.async_receive_from(
  51. boost::asio::buffer(data_, max_length), sender_endpoint_,
  52. boost::bind(&server::handle_receive_from, this,
  53. boost::asio::placeholders::error,
  54. boost::asio::placeholders::bytes_transferred));
  55. }
  56. private:
  57. udp::socket socket_;
  58. udp::endpoint sender_endpoint_;
  59. enum { max_length = 1024 };
  60. char data_[max_length];
  61. };
  62. int main(int argc, char* argv[])
  63. {
  64. try
  65. {
  66. if (argc != 2)
  67. {
  68. std::cerr << "Usage: async_udp_echo_server <port>\n";
  69. return 1;
  70. }
  71. boost::asio::io_context io_context;
  72. using namespace std; // For atoi.
  73. server s(io_context, atoi(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. }