connect_pair.cpp 3.3 KB

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