关于Transfer-Encoding: chunked类型的数据的解析

时间:2021-05-22 23:56:20

最近在写一个http文件下载模块,其中需要解析Transfer-Encoding: chunked类型的数据,找了一些相关的资料。

http://blog.csdn.net/zhangboyj/article/details/6236780

http://hi.baidu.com/ah__fu/blog/item/c3d47b2f0bcd65301e30891e.html


自己也写了一段解析从socket接收到的数据的代码

贴上函数:

//---------------------------------------------------------------------------    

//vSocket  套接字句柄

//vFwrite   文件句柄,用于写入解析得到的正确数据
int DownloadWithTrunk(FILE*& vFwrite, SOCKET& vSocket, int vSectSize, int vFileSize)
{
    DWORD tLen; 
    DWORD tSumLen=0; 
    char tBuffer[BUFFSIZE];
    char tChunkBuff[CHUNKSIZE];
    int tChunkSize = 0;
    int tBuffSize = 0;
    int tCurrentSectSize = 0;
    int tRemainingSize = 0;
    int tReturn = 0;


    while(1)
    {
        tLen = recv(vSocket, tBuffer, sizeof(tBuffer), 0);        if (tLen == SOCKET_ERROR){
            printf("Read error!\n");
            fclose(vFwrite);
            return -1;
        }
        tSumLen += tLen;
        printf("nSumLen: %d\n", tSumLen);
        if (tSumLen > 589000)
        {
            printf("begin debug\n");
        }


        if(tLen==0) break;
        memcpy(tChunkBuff + tChunkSize, tBuffer, tLen);
        tChunkSize += tLen;
        if((tReturn = AnalysisBuff(tChunkBuff, tChunkSize, vFwrite, tRemainingSize)) == 0)
            continue;
        else if (tReturn == 1)
            break;
        else
            return -1;
    }
    return 0;
}


重点看下面这个函数

其中函数参数tChunkBuff为待解析的chunk格式的数据流,解析完后写入tFwrite中,

//---------------------------------------------------------------------------
int AnalysisBuff(char* tChunkBuff, int& tChunkSize, FILE*& tFwrite, int& tChunkRemainingSize)
{
    if (tChunkRemainingSize > 0)
    {
        if (tChunkSize < tChunkRemainingSize)
        {
            tChunkRemainingSize -= tChunkSize;
           tChunkSize = 0;
           fwrite(tChunkBuff, tChunkSize, 1, tFwrite);
        }
        else
        {
            int tFileByte = fwrite(tChunkBuff, tChunkRemainingSize, 1, tFwrite);
            printf("fwrite getlasterror()%d \n", tFileByte);
            tChunkSize -= tChunkRemainingSize;
            memcpy(tChunkBuff, tChunkBuff + tChunkRemainingSize, tChunkSize);
            
            tChunkRemainingSize = 0;
            
        }


    }
    else
    {
        if (tChunkSize < 10)
        {
            return 0;
        }


        if (tChunkBuff[0] == '\r')
        {
            tChunkSize -= 2;
            memcpy(tChunkBuff, tChunkBuff + 2, tChunkSize);
        }


        char* tPChar = strstr(tChunkBuff, "\r\n");
        if (NULL == tPChar)
        {
            return -1;
        }
        int tLen = tPChar - tChunkBuff;
        char tNum[10];
        memcpy(tNum, tChunkBuff, tLen);
        tNum[tLen] = '\0';
        tChunkSize -= tLen + 2;
        memcpy(tChunkBuff, tChunkBuff + tLen + 2, tChunkSize);
        if((tChunkRemainingSize = HexToInt(tNum)) >= 0)
            AnalysisBuff(tChunkBuff, tChunkSize, tFwrite, tChunkRemainingSize);
        else if(tChunkRemainingSize == 0)
            return 1;
        else
            return -1;
    }
        
    return 0;
}