line_based.qbk 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. [/
  2. / Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  3. /
  4. / Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. /]
  7. [section:line_based Line-Based Operations]
  8. Many commonly-used internet protocols are line-based, which means that they
  9. have protocol elements that are delimited by the character sequence `"\r\n"`.
  10. Examples include HTTP, SMTP and FTP. To more easily permit the implementation
  11. of line-based protocols, as well as other protocols that use delimiters, Boost.Asio
  12. includes the functions `read_until()` and `async_read_until()`.
  13. The following example illustrates the use of `async_read_until()` in an HTTP
  14. server, to receive the first line of an HTTP request from a client:
  15. class http_connection
  16. {
  17. ...
  18. void start()
  19. {
  20. boost::asio::async_read_until(socket_, data_, "\r\n",
  21. boost::bind(&http_connection::handle_request_line, this, _1));
  22. }
  23. void handle_request_line(boost::system::error_code ec)
  24. {
  25. if (!ec)
  26. {
  27. std::string method, uri, version;
  28. char sp1, sp2, cr, lf;
  29. std::istream is(&data_);
  30. is.unsetf(std::ios_base::skipws);
  31. is >> method >> sp1 >> uri >> sp2 >> version >> cr >> lf;
  32. ...
  33. }
  34. }
  35. ...
  36. boost::asio::ip::tcp::socket socket_;
  37. boost::asio::streambuf data_;
  38. };
  39. The `streambuf` data member serves as a place to store the data that has been
  40. read from the socket before it is searched for the delimiter. It is important
  41. to remember that there may be additional data ['after] the delimiter. This
  42. surplus data should be left in the `streambuf` so that it may be inspected by a
  43. subsequent call to `read_until()` or `async_read_until()`.
  44. The delimiters may be specified as a single `char`, a `std::string` or a
  45. `boost::regex`. The `read_until()` and `async_read_until()` functions also
  46. include overloads that accept a user-defined function object called a match
  47. condition. For example, to read data into a streambuf until whitespace is
  48. encountered:
  49. typedef boost::asio::buffers_iterator<
  50. boost::asio::streambuf::const_buffers_type> iterator;
  51. std::pair<iterator, bool>
  52. match_whitespace(iterator begin, iterator end)
  53. {
  54. iterator i = begin;
  55. while (i != end)
  56. if (std::isspace(*i++))
  57. return std::make_pair(i, true);
  58. return std::make_pair(i, false);
  59. }
  60. ...
  61. boost::asio::streambuf b;
  62. boost::asio::read_until(s, b, match_whitespace);
  63. To read data into a streambuf until a matching character is found:
  64. class match_char
  65. {
  66. public:
  67. explicit match_char(char c) : c_(c) {}
  68. template <typename Iterator>
  69. std::pair<Iterator, bool> operator()(
  70. Iterator begin, Iterator end) const
  71. {
  72. Iterator i = begin;
  73. while (i != end)
  74. if (c_ == *i++)
  75. return std::make_pair(i, true);
  76. return std::make_pair(i, false);
  77. }
  78. private:
  79. char c_;
  80. };
  81. namespace boost { namespace asio {
  82. template <> struct is_match_condition<match_char>
  83. : public boost::true_type {};
  84. } } // namespace boost::asio
  85. ...
  86. boost::asio::streambuf b;
  87. boost::asio::read_until(s, b, match_char('a'));
  88. The `is_match_condition<>` type trait automatically evaluates to true for
  89. functions, and for function objects with a nested `result_type` typedef. For
  90. other types the trait must be explicitly specialised, as shown above.
  91. [heading See Also]
  92. [link boost_asio.reference.async_read_until async_read_until()],
  93. [link boost_asio.reference.is_match_condition is_match_condition],
  94. [link boost_asio.reference.read_until read_until()],
  95. [link boost_asio.reference.streambuf streambuf],
  96. [link boost_asio.examples.cpp03_examples.http_client HTTP client example].
  97. [endsect]