Imported Upstream version 1.64.0
[platform/upstream/boost.git] / doc / html / boost_asio / example / cpp03 / echo / async_tcp_echo_server.cpp
1 //
2 // async_tcp_echo_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 <cstdlib>
12 #include <iostream>
13 #include <boost/bind.hpp>
14 #include <boost/asio.hpp>
15
16 using boost::asio::ip::tcp;
17
18 class session
19 {
20 public:
21   session(boost::asio::io_service& io_service)
22     : socket_(io_service)
23   {
24   }
25
26   tcp::socket& socket()
27   {
28     return socket_;
29   }
30
31   void start()
32   {
33     socket_.async_read_some(boost::asio::buffer(data_, max_length),
34         boost::bind(&session::handle_read, this,
35           boost::asio::placeholders::error,
36           boost::asio::placeholders::bytes_transferred));
37   }
38
39 private:
40   void handle_read(const boost::system::error_code& error,
41       size_t bytes_transferred)
42   {
43     if (!error)
44     {
45       boost::asio::async_write(socket_,
46           boost::asio::buffer(data_, bytes_transferred),
47           boost::bind(&session::handle_write, this,
48             boost::asio::placeholders::error));
49     }
50     else
51     {
52       delete this;
53     }
54   }
55
56   void handle_write(const boost::system::error_code& error)
57   {
58     if (!error)
59     {
60       socket_.async_read_some(boost::asio::buffer(data_, max_length),
61           boost::bind(&session::handle_read, this,
62             boost::asio::placeholders::error,
63             boost::asio::placeholders::bytes_transferred));
64     }
65     else
66     {
67       delete this;
68     }
69   }
70
71   tcp::socket socket_;
72   enum { max_length = 1024 };
73   char data_[max_length];
74 };
75
76 class server
77 {
78 public:
79   server(boost::asio::io_service& io_service, short port)
80     : io_service_(io_service),
81       acceptor_(io_service, tcp::endpoint(tcp::v4(), port))
82   {
83     start_accept();
84   }
85
86 private:
87   void start_accept()
88   {
89     session* new_session = new session(io_service_);
90     acceptor_.async_accept(new_session->socket(),
91         boost::bind(&server::handle_accept, this, new_session,
92           boost::asio::placeholders::error));
93   }
94
95   void handle_accept(session* new_session,
96       const boost::system::error_code& error)
97   {
98     if (!error)
99     {
100       new_session->start();
101     }
102     else
103     {
104       delete new_session;
105     }
106
107     start_accept();
108   }
109
110   boost::asio::io_service& io_service_;
111   tcp::acceptor acceptor_;
112 };
113
114 int main(int argc, char* argv[])
115 {
116   try
117   {
118     if (argc != 2)
119     {
120       std::cerr << "Usage: async_tcp_echo_server <port>\n";
121       return 1;
122     }
123
124     boost::asio::io_service io_service;
125
126     using namespace std; // For atoi.
127     server s(io_service, atoi(argv[1]));
128
129     io_service.run();
130   }
131   catch (std::exception& e)
132   {
133     std::cerr << "Exception: " << e.what() << "\n";
134   }
135
136   return 0;
137 }