我正在编写一个小的客户端 HTTP 应用程序。它只是向 IP 摄像机发送 GET 请求,然后接收 jpeg 格式的屏幕截图。
现在我正在使用 Boost Asio 来实现 HTTP。因此,对于第一次尝试,我非常关注 sync_client 示例 Boost Asio Sync HTTP Client Example .
现在主要是我有点担心 Headers 和 Data 的分离。
首先我得到响应的第一行:
boost::asio::streambuf response;
boost::asio::read_until(*m_Socket, response, "\r\n");
std::istream response_stream(&response);
std::string http_version;
response_stream >> http_version;
if (!response_stream || http_version.substr(0, 5) != "HTTP/")
{
std::cout << "Invalid response\n";
return;
}
uint32_t status_code;
response_stream >> status_code;
std::string status_message;
std::getline(response_stream, status_message);
if (status_code != 200) // 200 = status code OK
{
std::cout << "Response returned with status code " << status_code << "\n";
return;
}
现在到这里一切对我来说都很清楚。我正在阅读直到第一行,然后检查缓冲区中的内容。
现在我正在尝试阅读标题的第二部分:
boost::asio::read_until(*m_Socket, response, "\r\n\r\n");
std::string header;
while (std::getline(response_stream, header) && (header != "\r"))
{
std::cout << header << "\n";
}
std::cout << "\n";
现在我有一些问题:
while 循环一直搜索直到出现空行(
\r
所在的唯一行)。现在,如果我假设新行由\r
定义,为什么我要在boost::asio::处使用
?我的意思是我希望两者兼而有之?\r\n\r\n
阅读直到如果我使用
\r\r
作为分隔符调用boost::asio::read_until
方法,它会抛出一个End of File
异常。这与我的 while 循环正在搜索的内容相反,因为它正在寻找\r\r
(因为它逐行查找,并且每一行都以\r
)
如您所见,我很担心如何在页眉中划分内容。它变得更糟,因为 boost::asio::read_until
调用确实总是比 delmiter 读得更远(这实际上没问题,因为它在文档中提到过),但它仍然有点总是相同数据的踪迹(来自实际的 jpeg),后面有相同的长度。
也许有人可以启发我?
最佳答案
'\r' 是回车 (CR) 字符,'\n' 是换行 (LF) 字符。 HTTP 消息行以“\r\n”(CRLF) 结束。
来自“HTTP 权威指南”:
It is worth pointing out that while the HTTP specification for terminating lines is CRLF, robust application also should accept just a line-feed character. Some older or broken HTTP applications do not always send both the carriage return and line feed.
似乎让您失望的是某些行 I/O 函数(在本例中为 std::getline())会自动去除尾随的 '\n',因此您只能看到前面的 '\r'。我认为你应该做的是寻找一个空白行(而不是只有'\r'的行)。并且只有 '\r' 的行应被视为空行。
关于c++ - 响应头和非 HTTP 数据的 HTTP 分离,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9212625/