]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/asio/example/cpp11/chat/chat_client.cpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / libs / asio / example / cpp11 / chat / chat_client.cpp
CommitLineData
7c673cae
FG
1//
2// chat_client.cpp
3// ~~~~~~~~~~~~~~~
4//
92f5a8d4 5// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
7c673cae
FG
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
18using boost::asio::ip::tcp;
19
20typedef std::deque<chat_message> chat_message_queue;
21
22class chat_client
23{
24public:
b32b8144
FG
25 chat_client(boost::asio::io_context& io_context,
26 const tcp::resolver::results_type& endpoints)
27 : io_context_(io_context),
28 socket_(io_context)
7c673cae 29 {
b32b8144 30 do_connect(endpoints);
7c673cae
FG
31 }
32
33 void write(const chat_message& msg)
34 {
b32b8144 35 boost::asio::post(io_context_,
7c673cae
FG
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 {
b32b8144 49 boost::asio::post(io_context_, [this]() { socket_.close(); });
7c673cae
FG
50 }
51
52private:
b32b8144 53 void do_connect(const tcp::resolver::results_type& endpoints)
7c673cae 54 {
b32b8144
FG
55 boost::asio::async_connect(socket_, endpoints,
56 [this](boost::system::error_code ec, tcp::endpoint)
7c673cae
FG
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
123private:
b32b8144 124 boost::asio::io_context& io_context_;
7c673cae
FG
125 tcp::socket socket_;
126 chat_message read_msg_;
127 chat_message_queue write_msgs_;
128};
129
130int 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
b32b8144 140 boost::asio::io_context io_context;
7c673cae 141
b32b8144
FG
142 tcp::resolver resolver(io_context);
143 auto endpoints = resolver.resolve(argv[1], argv[2]);
144 chat_client c(io_context, endpoints);
7c673cae 145
b32b8144 146 std::thread t([&io_context](){ io_context.run(); });
7c673cae
FG
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}