boost read_until不会停在分隔符处

时间:2013-11-28 00:54:34

标签: c++ sockets boost boost-asio istream

我正在使用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消息本身似乎格式正确。

1 个答案:

答案 0 :(得分:3)

文档似乎暗示了这一点:

  

“此函数用于将数据读入指定的streambuf   直到 streambuf的get区域包含指定的分隔符。“

但仔细看看:

  

直到 streambuf的获取区域包含 ...

所以,它不承诺停在那里。它只是在读取包含您的分隔符的块时立即返回给您。