Imported Upstream version 1.64.0
[platform/upstream/boost.git] / libs / asio / test / latency / tcp_server.cpp
1 //
2 // tcp_server.cpp
3 // ~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2017 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 <boost/asio/io_service.hpp>
12 #include <boost/asio/ip/tcp.hpp>
13 #include <boost/asio/read.hpp>
14 #include <boost/asio/write.hpp>
15 #include <boost/shared_ptr.hpp>
16 #include <cstdio>
17 #include <cstdlib>
18 #include <cstring>
19 #include <vector>
20
21 using boost::asio::ip::tcp;
22
23 #include "yield.hpp"
24
25 class tcp_server : coroutine
26 {
27 public:
28   tcp_server(tcp::acceptor& acceptor, std::size_t buf_size) :
29     acceptor_(acceptor),
30     socket_(acceptor_.get_io_service()),
31     buffer_(buf_size)
32   {
33   }
34
35   void operator()(boost::system::error_code ec, std::size_t n = 0)
36   {
37     reenter (this) for (;;)
38     {
39       yield acceptor_.async_accept(socket_, ref(this));
40
41       while (!ec)
42       {
43         yield boost::asio::async_read(socket_,
44             boost::asio::buffer(buffer_), ref(this));
45
46         if (!ec)
47         {
48           for (std::size_t i = 0; i < n; ++i) buffer_[i] = ~buffer_[i];
49
50           yield boost::asio::async_write(socket_,
51               boost::asio::buffer(buffer_), ref(this));
52         }
53       }
54
55       socket_.close();
56     }
57   }
58
59   struct ref
60   {
61     explicit ref(tcp_server* p)
62       : p_(p)
63     {
64     }
65
66     void operator()(boost::system::error_code ec, std::size_t n = 0)
67     {
68       (*p_)(ec, n);
69     }
70
71   private:
72     tcp_server* p_;
73   };
74
75 private:
76   tcp::acceptor& acceptor_;
77   tcp::socket socket_;
78   std::vector<unsigned char> buffer_;
79   tcp::endpoint sender_;
80 };
81
82 #include "unyield.hpp"
83
84 int main(int argc, char* argv[])
85 {
86   if (argc != 5)
87   {
88     std::fprintf(stderr,
89         "Usage: tcp_server <port> <nconns> "
90         "<bufsize> {spin|block}\n");
91     return 1;
92   }
93
94   unsigned short port = static_cast<unsigned short>(std::atoi(argv[1]));
95   int max_connections = std::atoi(argv[2]);
96   std::size_t buf_size = std::atoi(argv[3]);
97   bool spin = (std::strcmp(argv[4], "spin") == 0);
98
99   boost::asio::io_service io_service(1);
100   tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), port));
101   std::vector<boost::shared_ptr<tcp_server> > servers;
102
103   for (int i = 0; i < max_connections; ++i)
104   {
105     boost::shared_ptr<tcp_server> s(new tcp_server(acceptor, buf_size));
106     servers.push_back(s);
107     (*s)(boost::system::error_code());
108   }
109
110   if (spin)
111     for (;;) io_service.poll();
112   else
113     io_service.run();
114 }