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