stream_server.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. //
  2. // stream_server.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 <cstdio>
  11. #include <iostream>
  12. #include <boost/array.hpp>
  13. #include <boost/bind.hpp>
  14. #include <boost/enable_shared_from_this.hpp>
  15. #include <boost/shared_ptr.hpp>
  16. #include <boost/asio.hpp>
  17. #if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
  18. using boost::asio::local::stream_protocol;
  19. class session
  20. : public boost::enable_shared_from_this<session>
  21. {
  22. public:
  23. session(boost::asio::io_context& io_context)
  24. : socket_(io_context)
  25. {
  26. }
  27. stream_protocol::socket& socket()
  28. {
  29. return socket_;
  30. }
  31. void start()
  32. {
  33. socket_.async_read_some(boost::asio::buffer(data_),
  34. boost::bind(&session::handle_read,
  35. shared_from_this(),
  36. boost::asio::placeholders::error,
  37. boost::asio::placeholders::bytes_transferred));
  38. }
  39. void handle_read(const boost::system::error_code& error,
  40. size_t bytes_transferred)
  41. {
  42. if (!error)
  43. {
  44. boost::asio::async_write(socket_,
  45. boost::asio::buffer(data_, bytes_transferred),
  46. boost::bind(&session::handle_write,
  47. shared_from_this(),
  48. boost::asio::placeholders::error));
  49. }
  50. }
  51. void handle_write(const boost::system::error_code& error)
  52. {
  53. if (!error)
  54. {
  55. socket_.async_read_some(boost::asio::buffer(data_),
  56. boost::bind(&session::handle_read,
  57. shared_from_this(),
  58. boost::asio::placeholders::error,
  59. boost::asio::placeholders::bytes_transferred));
  60. }
  61. }
  62. private:
  63. // The socket used to communicate with the client.
  64. stream_protocol::socket socket_;
  65. // Buffer used to store data received from the client.
  66. boost::array<char, 1024> data_;
  67. };
  68. typedef boost::shared_ptr<session> session_ptr;
  69. class server
  70. {
  71. public:
  72. server(boost::asio::io_context& io_context, const std::string& file)
  73. : io_context_(io_context),
  74. acceptor_(io_context, stream_protocol::endpoint(file))
  75. {
  76. session_ptr new_session(new session(io_context_));
  77. acceptor_.async_accept(new_session->socket(),
  78. boost::bind(&server::handle_accept, this, new_session,
  79. boost::asio::placeholders::error));
  80. }
  81. void handle_accept(session_ptr new_session,
  82. const boost::system::error_code& error)
  83. {
  84. if (!error)
  85. {
  86. new_session->start();
  87. }
  88. new_session.reset(new session(io_context_));
  89. acceptor_.async_accept(new_session->socket(),
  90. boost::bind(&server::handle_accept, this, new_session,
  91. boost::asio::placeholders::error));
  92. }
  93. private:
  94. boost::asio::io_context& io_context_;
  95. stream_protocol::acceptor acceptor_;
  96. };
  97. int main(int argc, char* argv[])
  98. {
  99. try
  100. {
  101. if (argc != 2)
  102. {
  103. std::cerr << "Usage: stream_server <file>\n";
  104. std::cerr << "*** WARNING: existing file is removed ***\n";
  105. return 1;
  106. }
  107. boost::asio::io_context io_context;
  108. std::remove(argv[1]);
  109. server s(io_context, argv[1]);
  110. io_context.run();
  111. }
  112. catch (std::exception& e)
  113. {
  114. std::cerr << "Exception: " << e.what() << "\n";
  115. }
  116. return 0;
  117. }
  118. #else // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
  119. # error Local sockets not available on this platform.
  120. #endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)