我正在使用boost read_until函数来帮助通过套接字接收和解析HTTP消息。所以我尝试做的是从套接字read_until直到\r\n
,我认为应该给我一行HTTP头。 (根据标准,每个HTTP标题行以\r\n
结尾。)然而,我实际上从read_line获得的是整个标题,多行为多行。 (标题以\r\n\r\n
结尾,换句话说,空行。此外,根据HTTP标准。)这是一段代码片段。 sock
是套接字文件描述符。
boost::system::error_code err;
io::streambuf request_buff;
io::read_until(sock, request_buff, "\r\n", err); // read request line
if (err)
throw Exception(string("Failed to read HTTP header request line from socket: ") + err.message());
cerr << "Read " << request_buff.size() << " bytes." << endl;
istream request(&request_buff);
try {
request >> m_strMethod >> m_strPath >> m_strHttpVersion;
} catch (std::exception& e) {
throw Exception(string("Failed to parse HTTP header: ") + e.what(), e);
}
if (!request)
throw Exception("Failed to read HTTP header");
if (!alg::istarts_with(m_strHttpVersion, "HTTP/"))
throw Exception(string("Malformed HTTP header: expected HTTP version but got: ") + m_strHttpVersion);
string strTemp;
while (std::getline(request, strTemp))
{
cerr << "Extra line size = " << strTemp.size() << endl;
cerr << "Extra line: '" << strTemp << '\'' << endl;
}
我期望看到的是输出,表明它读取了HTTP消息第一行中的字节数,没有“额外”输出。我得到的是整个HTTP标头中的字节数,以及一个空白的额外行(这可能是因为&gt;&gt;操作没有消耗第一行末尾的换行符),后面是每隔一行在标题中,另一个空白行(表示标题的结尾,如上所述)。为什么read_until从套接字读取的内容比标题的第一行读取更多并将其放入request_buff中?
注意,我使用netcat接收请求,它正好通过。因此,HTTP消息本身似乎格式正确。
答案 0 :(得分:3)
文档似乎暗示了这一点:
“此函数用于将数据读入指定的streambuf 直到 streambuf的get区域包含指定的分隔符。“
但仔细看看:
直到 streambuf的获取区域包含 ...
所以,它不承诺停在那里。它只是在读取包含您的分隔符的块时立即返回给您。