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