0

我正在尝试使用 winsock 2 在 C++ 中实现 HTTP 请求。

连接到http://stackoverflow.com后,这是我发送的内容:

send(_socket, "GET / HTTP/1.1\r\nHost: www.stackoverflow.com\r\n\r\n", (the length ), 0);

现在阅读回复:

std::string s;
char buffer[BUFFER_LENGTH];
int bytes = 0;

do
{
    ZeroMemory(buffer, BUFFER_LENGTH);
    bytes = recv(_socket, buffer, BUFFER_LENGTH, 0);
    s.append(buffer);
} while (bytes == BUFFER_LENGTH);

return s;

顺便一提:#define BUFFER_LENGTH 512

这是奇怪的部分,当我运行程序时,我只得到响应的标题部分:

HTTP/1.1 200 OK

Cache-Control: public, max-age=34

Content-Type: text/html; charset=utf-8

Expires: Wed, 04 Sep 2013 08:14:00 GMT

Last-Modified: Wed, 04 Sep 2013 08:13:00 GMT

Vary: *

X-Frame-Options: SAMEORIGIN

Date: Wed, 04 Sep 2013 08:13:26 GMT

Content-Length: 193288

但是当我逐步调试读取功能时,我得到了包括内容在内的所有响应。如果我将断点放在 ZeroMemory() 函数上,然后按 F10 键(Step Over)继续执行代码,一次推进一个“命令”,循环继续几次然后存在并返回完整响应, 标题和内容。但是,如果我将断点放在 recv() 函数 (s.append(buffer)) 之后,则循环立即存在(仅在执行一次循环之后)并仅重新运行标头。

有人可以向我解释这种行为吗?

我假设在发送标头和内容之间存在某种定时延迟,因此当我在使用调试器的 recv() 之前停止时,服务器有足够的时间发送它,然后 recv() 可以读取它全部,但是当我把它放在后面时,服务器只有足够的时间来发送标头,recv() 函数只读取已经到达的内容,然后返回读取的少于 512 个字节,并且循环存在。我对吗?

提前致谢!

4

1 回答 1

0

假设是正确的,如评论中所述,如果数据尚未到达,您可以获得小于缓冲区大小的信息。您在循环中应该做的实际上是使用 HTTP 知识,例如查找\r\n\r\n标头何时到达,然后查找内容长度并尝试读取该内容的数据量。或者,由于您已经在Winsock2使用他们的方法HttpSendRequesthttp://msdn.microsoft.com/en-us/library/windows/desktop/aa384247(v=vs.85).aspx)和朋友 - 如果全部问题较少你想做的只是发送请求。

于 2013-09-04T08:50:41.610 回答