]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/asio/example/cpp03/chat/chat_client.cpp
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / boost / libs / asio / example / cpp03 / chat / chat_client.cpp
1 //
2 // chat_client.cpp
3 // ~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2020 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 <deque>
13 #include <iostream>
14 #include <boost/bind/bind.hpp>
15 #include <boost/asio.hpp>
16 #include <boost/thread/thread.hpp>
17 #include "chat_message.hpp"
18
19 using boost::asio::ip::tcp;
20
21 typedef std::deque<chat_message> chat_message_queue;
22
23 class chat_client
24 {
25 public:
26 chat_client(boost::asio::io_context& io_context,
27 const tcp::resolver::results_type& endpoints)
28 : io_context_(io_context),
29 socket_(io_context)
30 {
31 boost::asio::async_connect(socket_, endpoints,
32 boost::bind(&chat_client::handle_connect, this,
33 boost::asio::placeholders::error));
34 }
35
36 void write(const chat_message& msg)
37 {
38 boost::asio::post(io_context_,
39 boost::bind(&chat_client::do_write, this, msg));
40 }
41
42 void close()
43 {
44 boost::asio::post(io_context_,
45 boost::bind(&chat_client::do_close, this));
46 }
47
48 private:
49
50 void handle_connect(const boost::system::error_code& error)
51 {
52 if (!error)
53 {
54 boost::asio::async_read(socket_,
55 boost::asio::buffer(read_msg_.data(), chat_message::header_length),
56 boost::bind(&chat_client::handle_read_header, this,
57 boost::asio::placeholders::error));
58 }
59 }
60
61 void handle_read_header(const boost::system::error_code& error)
62 {
63 if (!error && read_msg_.decode_header())
64 {
65 boost::asio::async_read(socket_,
66 boost::asio::buffer(read_msg_.body(), read_msg_.body_length()),
67 boost::bind(&chat_client::handle_read_body, this,
68 boost::asio::placeholders::error));
69 }
70 else
71 {
72 do_close();
73 }
74 }
75
76 void handle_read_body(const boost::system::error_code& error)
77 {
78 if (!error)
79 {
80 std::cout.write(read_msg_.body(), read_msg_.body_length());
81 std::cout << "\n";
82 boost::asio::async_read(socket_,
83 boost::asio::buffer(read_msg_.data(), chat_message::header_length),
84 boost::bind(&chat_client::handle_read_header, this,
85 boost::asio::placeholders::error));
86 }
87 else
88 {
89 do_close();
90 }
91 }
92
93 void do_write(chat_message msg)
94 {
95 bool write_in_progress = !write_msgs_.empty();
96 write_msgs_.push_back(msg);
97 if (!write_in_progress)
98 {
99 boost::asio::async_write(socket_,
100 boost::asio::buffer(write_msgs_.front().data(),
101 write_msgs_.front().length()),
102 boost::bind(&chat_client::handle_write, this,
103 boost::asio::placeholders::error));
104 }
105 }
106
107 void handle_write(const boost::system::error_code& error)
108 {
109 if (!error)
110 {
111 write_msgs_.pop_front();
112 if (!write_msgs_.empty())
113 {
114 boost::asio::async_write(socket_,
115 boost::asio::buffer(write_msgs_.front().data(),
116 write_msgs_.front().length()),
117 boost::bind(&chat_client::handle_write, this,
118 boost::asio::placeholders::error));
119 }
120 }
121 else
122 {
123 do_close();
124 }
125 }
126
127 void do_close()
128 {
129 socket_.close();
130 }
131
132 private:
133 boost::asio::io_context& io_context_;
134 tcp::socket socket_;
135 chat_message read_msg_;
136 chat_message_queue write_msgs_;
137 };
138
139 int main(int argc, char* argv[])
140 {
141 try
142 {
143 if (argc != 3)
144 {
145 std::cerr << "Usage: chat_client <host> <port>\n";
146 return 1;
147 }
148
149 boost::asio::io_context io_context;
150
151 tcp::resolver resolver(io_context);
152 tcp::resolver::results_type endpoints = resolver.resolve(argv[1], argv[2]);
153
154 chat_client c(io_context, endpoints);
155
156 boost::thread t(boost::bind(&boost::asio::io_context::run, &io_context));
157
158 char line[chat_message::max_body_length + 1];
159 while (std::cin.getline(line, chat_message::max_body_length + 1))
160 {
161 using namespace std; // For strlen and memcpy.
162 chat_message msg;
163 msg.body_length(strlen(line));
164 memcpy(msg.body(), line, msg.body_length());
165 msg.encode_header();
166 c.write(msg);
167 }
168
169 c.close();
170 t.join();
171 }
172 catch (std::exception& e)
173 {
174 std::cerr << "Exception: " << e.what() << "\n";
175 }
176
177 return 0;
178 }