stream_server.cpp 2.5 KB

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