5 // Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
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)
11 #include <boost/asio/io_service.hpp>
12 #include <boost/asio/ip/udp.hpp>
13 #include <boost/shared_ptr.hpp>
18 #include "allocator.hpp"
20 using boost::asio::ip::udp;
24 class udp_server : coroutine
27 udp_server(boost::asio::io_service& io_service,
28 unsigned short port, std::size_t buf_size) :
29 socket_(io_service, udp::endpoint(udp::v4(), port)),
34 void operator()(boost::system::error_code ec, std::size_t n = 0)
36 reenter (this) for (;;)
38 yield socket_.async_receive_from(
39 boost::asio::buffer(buffer_),
44 for (std::size_t i = 0; i < n; ++i) buffer_[i] = ~buffer_[i];
45 socket_.send_to(boost::asio::buffer(buffer_, n), sender_, 0, ec);
50 friend void* asio_handler_allocate(std::size_t n, udp_server* s)
52 return s->allocator_.allocate(n);
55 friend void asio_handler_deallocate(void* p, std::size_t, udp_server* s)
57 s->allocator_.deallocate(p);
62 explicit ref(udp_server* p)
67 void operator()(boost::system::error_code ec, std::size_t n = 0)
75 friend void* asio_handler_allocate(std::size_t n, ref* r)
77 return asio_handler_allocate(n, r->p_);
80 friend void asio_handler_deallocate(void* p, std::size_t n, ref* r)
82 asio_handler_deallocate(p, n, r->p_);
88 std::vector<unsigned char> buffer_;
89 udp::endpoint sender_;
93 #include "unyield.hpp"
95 int main(int argc, char* argv[])
100 "Usage: udp_server <port1> <nports> "
101 "<bufsize> {spin|block}\n");
105 unsigned short first_port = static_cast<unsigned short>(std::atoi(argv[1]));
106 unsigned short num_ports = static_cast<unsigned short>(std::atoi(argv[2]));
107 std::size_t buf_size = std::atoi(argv[3]);
108 bool spin = (std::strcmp(argv[4], "spin") == 0);
110 boost::asio::io_service io_service(1);
111 std::vector<boost::shared_ptr<udp_server> > servers;
113 for (unsigned short i = 0; i < num_ports; ++i)
115 unsigned short port = first_port + i;
116 boost::shared_ptr<udp_server> s(new udp_server(io_service, port, buf_size));
117 servers.push_back(s);
118 (*s)(boost::system::error_code());
122 for (;;) io_service.poll();