gpt4 book ai didi

c++ - 使用 Winsock 接收分块的 HTTP 数据

转载 作者:太空狗 更新时间:2023-10-29 20:46:47 26 4
gpt4 key购买 nike

我在使用 winsock 读取一些分块的 HTTP 响应数据时遇到问题。我很好地发送了一个请求并得到了以下回复:

HTTP/1.1 200 OK
Server: LMAX/1.0
Content-Type: text/xml; charset=utf-8
Transfer-Encoding: chunked
Date: Mon, 29 Aug 2011 16:22:19 GMT

使用 winsock 接收。然而此时它只是挂起。我让监听器在无限循环中运行,但什么也听不到。

我认为这是一个 C++ 问题,但它也可能与我通过 stunnel 推送连接以将其包装在 HTTPS 中这一事实有关。我有一个使用 C# 中的一些库的测试应用程序,它可以通过 stunnel 完美运行。我很困惑为什么我的循环在初始接收后没有接收到 C++ 分块数据。

这是有问题的循环...它在上面的分块 ok 响应之后调用...

while(true)
{
recvBuf= (char*)calloc(DEFAULT_BUFLEN, sizeof(char));
iRes = recv(ConnectSocket, recvBuf, DEFAULT_BUFLEN, 0);
cout << WSAGetLastError() << endl;
cout << "Recv: " << recvBuf << endl;
if (iRes==SOCKET_ERROR)
{
cout << recvBuf << endl;
err = WSAGetLastError();
wprintf(L"WSARecv failed with error: %d\n", err);
break;
}

}

有什么想法吗?

最佳答案

您需要更改阅读代码。您不能像您尝试的那样使用固定长度的缓冲区读取 chunked 数据。数据以可变长度的 block 发送,其中每个 block 都有一个 header ,以字节为单位指定 block 的实际长度,数据的最后一个 block 的长度为 0。您需要读取分块 header 以便正确处理 block 。请阅读RFC 2616 Section 3.6.1 .您的逻辑需要更像以下伪代码:

send request;

status = recv() a line of text until CRLF;
parse status as needed;
response-code = extract response-code from status;
response-version = extract response-version from status;

do
{
line = recv() a line of text until CRLF;
if (line is blank)
break;
store line in headers list;
}
while (true);

parse headers list as needed;

if ((response-code is not in [1xx, 204, 304]) and (request was not "HEAD"))
{
if (Transfer-Encoding header is present and not "identity")
{
do
{
line = recv a line of text until CRLF;
length = extract length from line;
extensions = extract extensions from line;
process extensions as needed; // optional
if (length == 0)
break;
recv() length number of bytes into destination buffer;
recv() and discard bytes until CRLF;
}
while (true);

do
{
line = recv a line of text until CRLF;
if (line is blank)
break;
store line in headers list as needed;
}
while (true);

re-parse headers list as needed;
}
else if (Content-Length header is present)
{
recv() Content-Length number of bytes into destination buffer;
}
else if (Content-Type header starts with "multipart/")
{
boundary = extract boundary from Content-Type's "boundary" attribute;
recv() data into destination buffer until MIME termination boundary is reached;
}
else
{
recv() data into destination buffer until disconnected;
}
}

if (not disconnected)
{
if (response-version is "HTTP/1.1")
{
if (Connection header is "close")
close connection;
}
else
{
if (Connection header is not "keep-alive")
close connection;
}
}

check response-code for errors;
process destination buffer, per info in headers list;

关于c++ - 使用 Winsock 接收分块的 HTTP 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7232931/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com