c++ - 响应头和非 HTTP 数据的 HTTP 分离

标签 c++ http boost http-headers boost-asio

我正在编写一个小的客户端 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";

现在我有一些问题:

  1. while 循环一直搜索直到出现空行(\r 所在的唯一行)。现在,如果我假设新行由 \r 定义,为什么我要在 boost::asio::处使用 \r\n\r\n阅读直到?我的意思是我希望两者兼而有之?

  2. 如果我使用 \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/

相关文章:

c++ - 模板化构造函数的专用模板不会被调用

ios - 我需要对此代码进行无限循环的后台线程

python - 使用 ctypes 从 python 访问 boost::进程间共享内存块

C++ char** -> vector<string> -> string -> char** 解析问题

python - 如何确定是否从 Facebook iFrame 请求 url?

c++ - Visual Studio 2013 的 boost::fusion::invoke 编译器错误

c++ - stdio.h 和 iostream 之间有什么区别?

c++ - 它是正确的随机生成器函数吗?

c++ - 为什么类的默认构造函数和析构函数是内联的?

python - 如何在 flask 中获取请求的到达时间戳