【问题标题】:Parse Chunked HTTP response [duplicate]解析分块 HTTP 响应 [重复]
【发布时间】:2018-02-15 14:31:44
【问题描述】:

我正在使用 Winsock。我向服务器发送请求,HTTP 标头包含“Transfer-Encoding:chunked”。如果它们包含“Content-Length: xxxxx”,这很明显 - 但是如果数据被分块,我如何使用 recv() 将数据解析到缓冲区中?

一些伪代码或解释将不胜感激!

【问题讨论】:

  • 你试过谷歌搜索 http 分块传输编码吗?
  • @immibis 当然,我在用C,没有相关结果。
  • 您可能可以使用一个库来为您进行解析。
  • @Barmar 我正试图从头开始弄清楚如何做到这一点
  • 那么这是你必须自己解决的问题,因为它是特定于你的程序的。您可以看到,在分块编码中,响应有多个字节,然后是那么多字节,并且在字节数为 0 时结束。那么为什么不读取字节数,然后读取那么多字节,然后字节数为0时停止?

标签: c http winsock chunked-encoding


【解决方案1】:

假设你有一个套接字。已收到所有 HTTP 标头(来自此套接字)。这是从套接字接收分块内容的简化算法。

#define MAX_SIZE 1024

char *RecvChunked(SOCKET s)
{
    int chunk_length;
    char result[MAX_SIZE];
    char *result_ptr;

    memset(result,0,sizeof(result));

    for (chunk_length=0, result_ptr=result;;)
    {
        int recv_size;
        int size;

        if (chunk_length == 0) // get chunk length
        {
            char str[MAX_SIZE];
            char *ptr;

            // RecvLn
            for (ptr=str; ptr-str+sizeof(char) < sizeof(str);)
            {
                int ret = recv(s, ptr, sizeof(char), 0);
                if (ret <= 0)
                {
                    break;
                }

                if (*ptr != '\n')
                {
                    ptr += ret;
                    continue;
                }

                if (ptr-str <= 1)
                {
                    break;
                }

                if (*(ptr-1) == '\r')
                {
                    ptr --;
                }
                break;
            }

            *ptr = '\0';

            chunk_length = (int)strtol(str, NULL, 16); // HexToInt
        }
        recv_size = MIN(sizeof(result)-(result_ptr-result)-sizeof(char), chunk_length);

        if (recv_size == 0)
        {
            break; // nothing to receive
        }

        size = recv(s, result_ptr, recv_size, 0);

        if (chunk_length >= size)
        {
            chunk_length -= size;
        }
        else
        {
            chunk_length = 0;
        }

        result_ptr += size;

        if (size == 0)
        {
            // Disconnected ?
            break;
        }

        if (chunk_length == 0) // recv '\r\n' at the end of every chunk
        {
            char str[2];
            if (recv(s, str, sizeof(str), 0) < 2)
            {
                break; // Disconnect ?
            }
        }
    }
    return strdup(result);
}

此代码仅用于阐明如何从套接字解析分块内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-14
    • 2011-08-09
    相关资源
    最近更新 更多