【发布时间】:2013-09-04 08:36:56
【问题描述】:
我正在尝试使用 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 个字节,并且循环存在。我说的对吗?
提前致谢!
【问题讨论】:
-
重新阅读recv的文档。您可以获得较少的阅读量。
-
你真的应该检查错误或关闭的连接(即当
bytes <= 0时)。另请记住,如果目前没有更多可用数据,recv可以读取少于请求。 -
你看到不同行为取决于断点位置的原因是,如果你把断点放在
recv之前或之前,内部winsock缓冲区将有时间在你之前填满按 F10,因此当您执行recv时,更有可能(但不确定)您将获得请求的数据量。