1 //
2 // async_udp_echo_server.cpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2016 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 <cstdlib>
12 #include <iostream>
13 #include <boost/bind.hpp>
14 #include "asio.hpp"
15 
16 using asio::ip::udp;
17 
18 class server
19 {
20 public:
server(asio::io_context & io_context,short port)21   server(asio::io_context& io_context, short port)
22     : socket_(io_context, udp::endpoint(udp::v4(), port))
23   {
24     socket_.async_receive_from(
25         asio::buffer(data_, max_length), sender_endpoint_,
26         boost::bind(&server::handle_receive_from, this,
27           asio::placeholders::error,
28           asio::placeholders::bytes_transferred));
29   }
30 
handle_receive_from(const asio::error_code & error,size_t bytes_recvd)31   void handle_receive_from(const asio::error_code& error,
32       size_t bytes_recvd)
33   {
34     if (!error && bytes_recvd > 0)
35     {
36       socket_.async_send_to(
37           asio::buffer(data_, bytes_recvd), sender_endpoint_,
38           boost::bind(&server::handle_send_to, this,
39             asio::placeholders::error,
40             asio::placeholders::bytes_transferred));
41     }
42     else
43     {
44       socket_.async_receive_from(
45           asio::buffer(data_, max_length), sender_endpoint_,
46           boost::bind(&server::handle_receive_from, this,
47             asio::placeholders::error,
48             asio::placeholders::bytes_transferred));
49     }
50   }
51 
handle_send_to(const asio::error_code &,size_t)52   void handle_send_to(const asio::error_code& /*error*/,
53       size_t /*bytes_sent*/)
54   {
55     socket_.async_receive_from(
56         asio::buffer(data_, max_length), sender_endpoint_,
57         boost::bind(&server::handle_receive_from, this,
58           asio::placeholders::error,
59           asio::placeholders::bytes_transferred));
60   }
61 
62 private:
63   udp::socket socket_;
64   udp::endpoint sender_endpoint_;
65   enum { max_length = 1024 };
66   char data_[max_length];
67 };
68 
main(int argc,char * argv[])69 int main(int argc, char* argv[])
70 {
71   try
72   {
73     if (argc != 2)
74     {
75       std::cerr << "Usage: async_udp_echo_server <port>\n";
76       return 1;
77     }
78 
79     asio::io_context io_context;
80 
81     using namespace std; // For atoi.
82     server s(io_context, atoi(argv[1]));
83 
84     io_context.run();
85   }
86   catch (std::exception& e)
87   {
88     std::cerr << "Exception: " << e.what() << "\n";
89   }
90 
91   return 0;
92 }
93