line_based.qbk

来自「Boost provides free peer-reviewed portab」· QBK 代码 · 共 119 行

QBK
119
字号
[/ / Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com) / / Distributed under the Boost Software License, Version 1.0. (See accompanying / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) /][section:line_based Line-Based Operations]Many commonly-used internet protocols are line-based, which means that theyhave protocol elements that are delimited by the character sequence `"\r\n"`.Examples include HTTP, SMTP and FTP. To more easily permit the implementationof line-based protocols, as well as other protocols that use delimiters, Boost.Asioincludes the functions `read_until()` and `async_read_until()`.The following example illustrates the use of `async_read_until()` in an HTTPserver, to receive the first line of an HTTP request from a client:  class http_connection  {    ...    void start()    {      boost::asio::async_read_until(socket_, data_, "\r\n",          boost::bind(&http_connection::handle_request_line, this, _1));    }    void handle_request_line(boost::system::error_code ec)    {      if (!ec)      {        std::string method, uri, version;        char sp1, sp2, cr, lf;        std::istream is(&data_);        is.unsetf(std::ios_base::skipws);        is >> method >> sp1 >> uri >> sp2 >> version >> cr >> lf;        ...      }    }    ...    boost::asio::ip::tcp::socket socket_;    boost::asio::streambuf data_;  };The `streambuf` data member serves as a place to store the data that has beenread from the socket before it is searched for the delimiter. It is importantto remember that there may be additional data ['after] the delimiter. Thissurplus data should be left in the `streambuf` so that it may be inspected by asubsequent call to `read_until()` or `async_read_until()`.The delimiters may be specified as a single `char`, a `std::string` or a`boost::regex`. The `read_until()` and `async_read_until()` functions alsoinclude overloads that accept a user-defined function object called a matchcondition. For example, to read data into a streambuf until whitespace isencountered:  typedef boost::asio::buffers_iterator<      boost::asio::streambuf::const_buffers_type> iterator;  std::pair<iterator, bool>  match_whitespace(iterator begin, iterator end)  {    iterator i = begin;    while (i != end)      if (std::isspace(*i++))        return std::make_pair(i, true);    return std::make_pair(i, false);  }  ...  boost::asio::streambuf b;  boost::asio::read_until(s, b, match_whitespace);To read data into a streambuf until a matching character is found:  class match_char  {  public:    explicit match_char(char c) : c_(c) {}    template <typename Iterator>    std::pair<Iterator, bool> operator()(        Iterator begin, Iterator end) const    {      Iterator i = begin;      while (i != end)        if (c_ == *i++)          return std::make_pair(i, true);      return std::make_pair(i, false);    }  private:    char c_;  };  namespace boost { namespace asio {    template <> struct is_match_condition<match_char>      : public boost::true_type {};  } } // namespace boost::asio  ...  boost::asio::streambuf b;  boost::asio::read_until(s, b, match_char('a'));The `is_match_condition<>` type trait automatically evaluates to true forfunctions, and for function objects with a nested `result_type` typedef. Forother types the trait must be explicitly specialised, as shown above.[heading See Also][link boost_asio.reference.async_read_until async_read_until()],[link boost_asio.reference.is_match_condition is_match_condition],[link boost_asio.reference.read_until read_until()],[link boost_asio.reference.streambuf streambuf],[link boost_asio.examples.http_client HTTP client example].[endsect]

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?