我只是在写一个小客户端HTTP应用程序。它只是向IP摄像机发送GET请求,然后以jpeg格式接收屏幕截图。
现在为了实现HTTP我正在使用Boost Asio。因此,对于第一次尝试,我几乎都在sync_client示例Boost Asio Sync HTTP Client Example。
现在主要是我对标题和数据的分离感到有点担心。
首先我得到回复的第一行:
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
定义了新行,为什么我在\r\n\r\n
使用boost::asio::read_until
?我的意思是我会期待一个或另一个,但两者都是?
如果我使用boost::asio::read_until
作为分隔符调用\r\r
方法,则会抛出End of File
异常。这与我的while循环搜索相反,因为它正在寻找\r\r
(因为它看起来是一行一行,每行都以\r
结束)
所以你可以看到我非常担心如何在我的标题内划分东西。它越来越甚至沃瑟因为boost::asio::read_until
调用并总是比delmiter进一步阅读(其实这是正常的,因为它在文档中真实提到),但仍有点始终具有相同的数据跟踪(从actualy JPEG) ,跟随长度相同。
也许有人可以启发我?
答案 0 :(得分:3)
'\ r'是回车符(CR)字符,'\ n'是换行符(LF)字符。 HTTP消息行以“\ r \ n”(CRLF)终止。
来自“HTTP The Definitive Guide”:
值得指出的是,虽然是HTTP规范 终止线是CRLF,强大的应用也应该接受 换行符。一些较旧或损坏的HTTP应用程序不会 总是发送回车和换行。
似乎让你失望的是,某些行I / O函数(在本例中为std :: getline())会自动删除尾部'\ n',因此您只能看到前面的'\ r'。我认为你应该做的是寻找一个空行(而不是只有'\ r'的行)。并且只有'\ r'的行应该被视为空行。
答案 1 :(得分:2)
"\r\n\r\n"
分隔符用于将标题与实际服务器的响应(您正在获取的JPEG图像)分开。这就是你使用它的原因;标题由"\r\n"
分隔。
您应该阅读"\r\n\r\n"
。之后发生的一切都是JPEG图像。请注意,您可以通过检查Content-Length标头来猜测文件的长度,或者直到服务器关闭套接字才能读取。