【发布时间】:2012-03-27 14:53:40
【问题描述】:
实现一个 boost::asio::async_read_until 版本的最简单方法是什么,它只在找到分隔符之前读取?我可以实现一个知道如何消耗适当字节数的特殊匹配条件吗?如果没有,那么我如何编写一个检查每个字节的异步阅读器?
我需要阻止提供的 streambuf 消耗超出分隔符的字节。
【问题讨论】:
标签: boost boost-asio
实现一个 boost::asio::async_read_until 版本的最简单方法是什么,它只在找到分隔符之前读取?我可以实现一个知道如何消耗适当字节数的特殊匹配条件吗?如果没有,那么我如何编写一个检查每个字节的异步阅读器?
我需要阻止提供的 streambuf 消耗超出分隔符的字节。
【问题讨论】:
标签: boost boost-asio
在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);
【讨论】:
我需要阻止提供的 streambuf 消耗超出 分隔符。
实现这一点的唯一方法是(低效地)一次从流中读取一个字节。我不会建议这种方法,documentation 很容易描述如何处理这种情况
async_read_until 操作成功后,streambuf 可能 包含超出分隔符的附加数据。一个应用程序将 通常将该数据留在 streambuf 中以供后续使用 async_read_until 操作来检查。
这正是异步 http 客户端 example 所做的。
【讨论】:
我想指出this document中的REMARK实际上是不正确的,无论我测试多少次。
备注 async_read_until 操作成功后,streambuf 可能包含超出功能匹配的附加数据 目的。应用程序通常会将该数据留在流缓冲区中 供后续的 async_read_until 操作检查。
MatchCondition 仿函数应该消耗流缓冲区中的所有内容,不要为下一次 async_read_until() 调用留下未消耗的字节,否则您的应用程序可能会永远等待。
附言测试设置是 x86-64 centos4.3 kernel-2.6.32 gcc4.8
【讨论】: