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