其他分享
首页 > 其他分享> > c – 使用Winsock接收分块的HTTP数据

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

作者:互联网

我在使用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 recv.在这一点上,它只是挂起.我让听众在一个无限循环中运行,但没有任何东西被拾起.

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

这是有问题的循环…它是在上面的chunked 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;
    }     

}

有任何想法吗?

解决方法:

您需要更改阅读代码.您不能像使用固定长度的缓冲区那样读取分块数据.数据以可变长度的块发送,其中每个块都有一个标头,用于指定块的实际长度(以字节为单位),最后一块数据的长度为0.您需要读取分块标头以便正确处理块.请阅读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;

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/")
    {
        recv() data into destination buffer until MIME terminator derived from the Content-Type's "boundary" attribute value is reached;
    }
    else
    {
        recv() data into destination buffer until disconnected;
    }
}

标签:http-get,winsock,chunked,c,stunnel
来源: https://codeday.me/bug/20190903/1794898.html