最近在写一个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;
}