5 // Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
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)
15 #include <boost/asio.hpp>
16 #include "chat_message.hpp"
18 using boost::asio::ip::tcp
;
20 typedef std::deque
<chat_message
> chat_message_queue
;
25 chat_client(boost::asio::io_context
& io_context
,
26 const tcp::resolver::results_type
& endpoints
)
27 : io_context_(io_context
),
30 do_connect(endpoints
);
33 void write(const chat_message
& msg
)
35 boost::asio::post(io_context_
,
38 bool write_in_progress
= !write_msgs_
.empty();
39 write_msgs_
.push_back(msg
);
40 if (!write_in_progress
)
49 boost::asio::post(io_context_
, [this]() { socket_
.close(); });
53 void do_connect(const tcp::resolver::results_type
& endpoints
)
55 boost::asio::async_connect(socket_
, endpoints
,
56 [this](boost::system::error_code ec
, tcp::endpoint
)
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*/)
71 if (!ec
&& read_msg_
.decode_header())
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*/)
90 std::cout
.write(read_msg_
.body(), read_msg_
.body_length());
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*/)
110 write_msgs_
.pop_front();
111 if (!write_msgs_
.empty())
124 boost::asio::io_context
& io_context_
;
126 chat_message read_msg_
;
127 chat_message_queue write_msgs_
;
130 int main(int argc
, char* argv
[])
136 std::cerr
<< "Usage: chat_client <host> <port>\n";
140 boost::asio::io_context io_context
;
142 tcp::resolver
resolver(io_context
);
143 auto endpoints
= resolver
.resolve(argv
[1], argv
[2]);
144 chat_client
c(io_context
, endpoints
);
146 std::thread
t([&io_context
](){ io_context
.run(); });
148 char line
[chat_message::max_body_length
+ 1];
149 while (std::cin
.getline(line
, chat_message::max_body_length
+ 1))
152 msg
.body_length(std::strlen(line
));
153 std::memcpy(msg
.body(), line
, msg
.body_length());
161 catch (std::exception
& e
)
163 std::cerr
<< "Exception: " << e
.what() << "\n";