1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
//
// connect_pair.cpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2023 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 <array>
#include <iostream>
#include <string>
#include <cctype>
#include <boost/asio.hpp>
#include <boost/thread/thread.hpp>
#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
using boost::asio::local::stream_protocol;
class uppercase_filter
{
public:
uppercase_filter(stream_protocol::socket sock)
: socket_(std::move(sock))
{
read();
}
private:
void read()
{
socket_.async_read_some(boost::asio::buffer(data_),
[this](boost::system::error_code ec, std::size_t size)
{
if (!ec)
{
// Compute result.
for (std::size_t i = 0; i < size; ++i)
data_[i] = std::toupper(data_[i]);
// Send result.
write(size);
}
else
{
throw boost::system::system_error(ec);
}
});
}
void write(std::size_t size)
{
boost::asio::async_write(socket_, boost::asio::buffer(data_, size),
[this](boost::system::error_code ec, std::size_t /*size*/)
{
if (!ec)
{
// Wait for request.
read();
}
else
{
throw boost::system::system_error(ec);
}
});
}
stream_protocol::socket socket_;
std::array<char, 512> data_;
};
int main()
{
try
{
boost::asio::io_context io_context;
// Create a connected pair and pass one end to a filter.
stream_protocol::socket socket(io_context);
stream_protocol::socket filter_socket(io_context);
boost::asio::local::connect_pair(socket, filter_socket);
uppercase_filter filter(std::move(filter_socket));
// The io_context runs in a background thread to perform filtering.
boost::thread thread(
[&io_context]()
{
try
{
io_context.run();
}
catch (std::exception& e)
{
std::cerr << "Exception in thread: " << e.what() << "\n";
std::exit(1);
}
});
for (;;)
{
// Collect request from user.
std::cout << "Enter a string: ";
std::string request;
std::getline(std::cin, request);
// Send request to filter.
boost::asio::write(socket, boost::asio::buffer(request));
// Wait for reply from filter.
std::vector<char> reply(request.size());
boost::asio::read(socket, boost::asio::buffer(reply));
// Show reply to user.
std::cout << "Result: ";
std::cout.write(&reply[0], request.size());
std::cout << std::endl;
}
}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << "\n";
std::exit(1);
}
}
#else // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
# error Local sockets not available on this platform.
#endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
|