Asio Line-Based Operations

许多常用的internet协议是基于行的,这意味着他们具有由字符序列"\r\n"分隔的协议元素。这样的协议有HTTP、SMTP和FTP。为更容易实现基于行的协议以及其他使用分隔符的协议,Asio包括read_until()和async_read_until()函数。
以下例子说明了在HTTP服务器中使用async_read_until()用来接收来自客户端请求的第1行:

class http_connection
{
  ...

  void start()
  {
    asio::async_read_until(socket_, data_, "\r\n",
        boost::bind(&http_connection::handle_request_line, this, _1));
  }

  void handle_request_line(asio::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;
      ...
    }
  }

  ...

  asio::ip::tcp::socket socket_;
  asio::streambuf data_;
};

streambuf数据成员用作存储从socket读取的在搜索到分隔符之前的数据。重要的是要记住在分隔符之后可能还有其他数据。这些多余的数据应该留在streambuf中,以便随后调用read_until()或async_read_until()来检查它。
分隔符可以被指定为单个字符、std::string或者boost::regex, read_until()和async_read_until()函数还包括接受用户定义的函数对象作为匹配条件的重载。例如读取数据到一个streambuf中直到遇见空格:

typedef asio::buffers_iterator<
    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);
}
...
asio::streambuf b;
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 asio {
  template <> struct is_match_condition<match_char>
    : public boost::true_type {};
} // namespace asio
...
asio::streambuf b;
asio::read_until(s, b, match_char('a'));

is_match_condition<> 对于函数和具有嵌套result_type typedef的函数对象自动评估为true. 对于其他类型,必须显示特化,如上所示。

原文

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值