基于行的操作
许多常用的互联网协议是基于行的,这意味着它们的协议元素由字符序列 "\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() 进行检查。
分隔符可以指定为单个字符、std::string 或 boost::regex。read_until() 和 async_read_until() 函数还包括接受用户定义的函数对象作为匹配条件的重载。例如,要读取数据到 streambuf,直到遇到空白字符:
要读取数据到 streambuf,直到找到匹配的字符:
is_match_condition<> 类型特征会自动对函数和具有嵌套 result_type typedef 的函数对象评估为 true。如上所示,对于其他类型,特征必须显式特化。
async_read_until(), is_match_condition, read_until(), streambuf, HTTP client example.
Last updated