@john-lee
2021-01-03T02:41:31.000000Z
字数 2073
阅读 772
Boost.Asio
许多常用的 internet 协议是基于行的,这意味着它们具有由字符序列“\r\n”分隔的协议元素。例如 HTTP、SMTP 和 FTP。为了更容易地实现基于行的协议以及使用分隔符的其他协议,Boost.Asio 包括函数read_until()和async_read_until()。
下面的示例说明如何在 HTTP 服务器中使用async_read_until()从客户端接收 HTTP 请求的第一行:
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_;};
streambuf数据成员用作存储在搜索分隔符之前从套接字读取的数据的位置。请务必记住,分隔符后面可能还有其他数据。剩余的数据应该留在streambuf中,以便后续的read_until()或async_read_until()调用可以检查它。
分隔符可以指定为单个char、std::string或boost::regex。read_until()和async_read_until()函数还包括接受称为匹配条件的用户定义函数对象的重载。例如,将数据读取到streambuf,直到遇到空白:
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);
要将数据读取到streambuf中,直到找到匹配的字符:
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'));
对于函数和typedef的嵌套result_type类型的函数对象,is_match_condition<>类型特征会自动计算为 true。对于其他类型的特征必须明确特化,如上所示。
async_read_until()、is_match_condition read_until()、streambuf、HTTP 客户端示例。
Copyright © 2003-2020 Christopher M. Kohlhoff
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)