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 131 132 133 134 135 136 137 138 139 140 141 142
|
//
// connect_pair.cpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2013 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 <iostream>
#include <string>
#include <cctype>
#include <boost/asio.hpp>
#include <boost/thread/thread.hpp>
#include <boost/array.hpp>
#include <boost/bind.hpp>
#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
using boost::asio::local::stream_protocol;
class uppercase_filter
{
public:
uppercase_filter(boost::asio::io_service& io_service)
: socket_(io_service)
{
}
stream_protocol::socket& socket()
{
return socket_;
}
void start()
{
// Wait for request.
socket_.async_read_some(boost::asio::buffer(data_),
boost::bind(&uppercase_filter::handle_read,
this, boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
private:
void handle_read(const 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.
boost::asio::async_write(socket_, boost::asio::buffer(data_, size),
boost::bind(&uppercase_filter::handle_write,
this, boost::asio::placeholders::error));
}
else
{
throw boost::system::system_error(ec);
}
}
void handle_write(const boost::system::error_code& ec)
{
if (!ec)
{
// Wait for request.
socket_.async_read_some(boost::asio::buffer(data_),
boost::bind(&uppercase_filter::handle_read,
this, boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else
{
throw boost::system::system_error(ec);
}
}
stream_protocol::socket socket_;
boost::array<char, 512> data_;
};
void run(boost::asio::io_service* io_service)
{
try
{
io_service->run();
}
catch (std::exception& e)
{
std::cerr << "Exception in thread: " << e.what() << "\n";
std::exit(1);
}
}
int main()
{
try
{
boost::asio::io_service io_service;
// Create filter and establish a connection to it.
uppercase_filter filter(io_service);
stream_protocol::socket socket(io_service);
boost::asio::local::connect_pair(socket, filter.socket());
filter.start();
// The io_service runs in a background thread to perform filtering.
boost::thread thread(boost::bind(run, &io_service));
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)
|