实现真正 boost::asio::async_read_until 的最简单方法

Posted

技术标签:

【中文标题】实现真正 boost::asio::async_read_until 的最简单方法【英文标题】:Easiest way to implement a true boost::asio::async_read_until 【发布时间】:2012-03-27 14:53:40 【问题描述】:

实现一个 boost::asio::async_read_until 版本的最简单方法是什么,它只在找到分隔符之前读取?我可以实现一个知道如何消耗适当字节数的特殊匹配条件吗?如果没有,那么我如何编写一个检查每个字节的异步阅读器?

我需要阻止提供的 streambuf 消耗超出分隔符的字节。

【问题讨论】:

【参考方案1】:

在documentation可以找到一个简单的匹配函数:

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);

在这种情况下,它匹配任何空格(根据您的需要更改 std::isspace)。同样在该文档中,您可以看到一个更复杂的事件,它消耗流直到找到特定字符:

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_;
;

以及使用该类的代码:

// Function used for error handling
void handler(const boost::system::error_code& e, std::size_t size)

 // Do something


// Example of call, it reads from inputStream to outputStreamBuff
// until the specified delimiter (";") is found
boost::asio::async_read_until(inputStream, outputStreamBuff,
   match_char(';'), handler);

【讨论】:

【参考方案2】:

我需要阻止提供的 streambuf 消耗超出 分隔符。

实现这一点的唯一方法是(低效地)一次从流中读取一个字节。我不会建议这种方法,documentation 很容易描述如何处理这种情况

async_read_until 操作成功后,streambuf 可能 包含超出分隔符的附加数据。一个应用程序将 通常将该数据留在 streambuf 中以供后续使用 async_read_until 操作来检查。

这正是异步 http 客户端 example 所做的。

【讨论】:

【参考方案3】:

我想指出this document中的REMARK实际上是不正确的,无论我测试多少次。

备注 async_read_until 操作成功后,streambuf 可能包含超出功能匹配的附加数据 目的。应用程序通常会将该数据留在流缓冲区中 供后续的 async_read_until 操作检查。

MatchCondition 仿函数应该消耗流缓冲区中的所有内容,不要为下一次 async_read_until() 调用留下未消耗的字节,否则您的应用程序可能会永远等待。

附言测试设置是 x86-64 centos4.3 kernel-2.6.32 gcc4.8

【讨论】:

更多测试设置:boost_1-59-0

以上是关于实现真正 boost::asio::async_read_until 的最简单方法的主要内容,如果未能解决你的问题,请参考以下文章

实现“真正的”单点登录:OpenID、其他东西还是自定义黑客?

SecureRandom 的 Android 实现是不是会产生真正的随机数?

敏捷开发怎么真正实现落地

华为OD机试真题 JavaScript 实现真正的密码2023 Q1 | 100分

华为OD机试真题 JavaScript 实现真正的密码2023 Q1 | 100分

华为机试真题 Python 实现真正的密码2022.11 Q4 新题