zoukankan      html  css  js  c++  java
  • 基于行的操作

    许多广泛应用的网络协议是基于行的,这意味着许多协议元素通过" "来分割,比如HTTP、SMPT、FTP,为了更方便的实现基于行的协议,和其他基于分隔符的协议一样,Boost::Asio包括了read_until() 和async_read_until()。
    下面的例子阐述了async_read_until() 在HTTP server的应用,为了从HTTP client接收第一行
    class http_connection
    {
      ...
      void start()
      {
        boost::asio::async_read_until(socket_, data_, " ",
            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的数据成员保存了从socket接收到的没有被分割的数据,在分隔符后面还可能有很多数据,多余的数据应当留在streambuf 中,并使用read_until() 或者 async_read_until()来检查子序列
    分隔符可能是一个单独的char,一个std::string或者boost::regex,read_until() 和 async_read_until() 也包含了用户自定义函数对象作为匹配条件的重载,比如,一直读数据直到遇到一个空白字符
    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);
    从流缓存中读数据,知道遇到一个匹配的字符
    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'));
    is_match_condition<> 自动评估函数的结果是true还是false,以及拥有前台的result_type 定义的函数对象。其他类型必须显式指定,就像上面写的那样
  • 相关阅读:
    vim 常用命令
    centos 安装mysql
    centos部署ftp
    centos 6.8部署nginx
    ndk学习16: unix domain socket
    ndk学习14: 进程
    ndk学习13: proc
    ndk学习11: linux内存管理
    ndk学习10: linux文件系统
    ndk学习9: 动态使用共享库
  • 原文地址:https://www.cnblogs.com/learn-my-life/p/5272220.html
Copyright © 2011-2022 走看看