Created
February 8, 2018 14:52
-
-
Save edouarda/03ff91ccd254214d489f8d18af62133f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// chat_client.cpp | |
// ~~~~~~~~~~~~~~~ | |
// | |
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) | |
// | |
// Distributed under the Boost Software License, Version 1.0. (See accompanying | |
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
// | |
#include "../chat_message.hpp" | |
#include <boost/asio.hpp> | |
#include <cstdlib> | |
#include <deque> | |
#include <iostream> | |
#include <thread> | |
using boost::asio::ip::tcp; | |
typedef std::deque<chat_message> chat_message_queue; | |
class chat_client | |
{ | |
public: | |
chat_client(boost::asio::io_context & io_context, | |
const tcp::resolver::results_type & endpoints) | |
: io_context_(io_context) | |
, socket_(io_context) | |
{ | |
do_connect(endpoints); | |
} | |
void write(const chat_message & msg) | |
{ | |
boost::asio::post(io_context_, [this, msg]() { | |
bool write_in_progress = !write_msgs_.empty(); | |
write_msgs_.push_back(msg); | |
if (!write_in_progress) | |
{ | |
do_write(); | |
} | |
}); | |
} | |
void close() | |
{ | |
boost::asio::post(io_context_, [this]() { socket_.close(); }); | |
} | |
private: | |
void do_connect(const tcp::resolver::results_type & endpoints) | |
{ | |
boost::asio::async_connect(socket_, endpoints, | |
[this](boost::system::error_code ec, tcp::endpoint) { | |
if (!ec) | |
{ | |
do_read_header(); | |
} | |
}); | |
} | |
void do_read_header() | |
{ | |
boost::asio::async_read(socket_, | |
boost::asio::buffer(read_msg_.data(), chat_message::header_length), | |
[this](boost::system::error_code ec, std::size_t /*length*/) { | |
if (!ec && read_msg_.decode_header()) | |
{ | |
do_read_body(); | |
} | |
else | |
{ | |
socket_.close(); | |
} | |
}); | |
} | |
void do_read_body() | |
{ | |
boost::asio::async_read(socket_, | |
boost::asio::buffer(read_msg_.body(), read_msg_.body_length()), | |
[this](boost::system::error_code ec, std::size_t /*length*/) { | |
if (!ec) | |
{ | |
std::cout.write(read_msg_.body(), read_msg_.body_length()); | |
std::cout << "\n"; | |
do_read_header(); | |
} | |
else | |
{ | |
socket_.close(); | |
} | |
}); | |
} | |
void do_write() | |
{ | |
boost::asio::async_write(socket_, | |
boost::asio::buffer( | |
write_msgs_.front().data(), write_msgs_.front().length()), | |
[this](boost::system::error_code ec, std::size_t /*length*/) { | |
if (!ec) | |
{ | |
write_msgs_.pop_front(); | |
if (!write_msgs_.empty()) | |
{ | |
do_write(); | |
} | |
} | |
else | |
{ | |
socket_.close(); | |
} | |
}); | |
} | |
private: | |
boost::asio::io_context & io_context_; | |
tcp::socket socket_; | |
chat_message read_msg_; | |
chat_message_queue write_msgs_; | |
}; | |
int main(int argc, char * argv[]) | |
{ | |
try | |
{ | |
if (argc != 3) | |
{ | |
std::cerr << "Usage: chat_client <host> <port>\n"; | |
return 1; | |
} | |
boost::asio::io_context io_context; | |
tcp::resolver resolver(io_context); | |
auto endpoints = resolver.resolve(argv[1], argv[2]); | |
std::thread t([&io_context]() { io_context.run(); }); | |
for (size_t i = 0; i < 1024; ++i) | |
{ | |
chat_client c(io_context, endpoints); | |
// char line[chat_message::max_body_length + 1]; | |
/* while (std::cin.getline(line, chat_message::max_body_length + 1)) | |
{ | |
chat_message msg; | |
msg.body_length(std::strlen(line)); | |
std::memcpy(msg.body(), line, msg.body_length()); | |
msg.encode_header(); | |
c.write(msg); | |
} */ | |
c.close(); | |
} | |
t.join(); | |
} | |
catch (std::exception & e) | |
{ | |
std::cerr << "Exception: " << e.what() << "\n"; | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment