比如大家可以抓包看一下
http://www.flyrom.com/PHPWind_UTF8_4.3.2/upload/ck.php?windid=真郁闷,如果不但不返回Content-Length 而且HTTP协议头后面(#13#10#13#10)并不是正文的开始,而是 XXX+空格+空格+#13#10后面才是正文注:
XXX有时候是16进制的正文长度比如“d3af8”此时后面的2个空格是没有的,这样我也可以计算到长度并处理。
但有时候则是完全无意义的数字,真是搞不懂。不过浏览器倒是完全可以处理这种情况,不知道是如何处理的。我看了HTTP的RFC但是找不到,或者哪位仁兄发来详细的HTTP RFC文档。
http://www.flyrom.com/PHPWind_UTF8_4.3.2/upload/ck.php?windid=真郁闷,如果不但不返回Content-Length 而且HTTP协议头后面(#13#10#13#10)并不是正文的开始,而是 XXX+空格+空格+#13#10后面才是正文注:
XXX有时候是16进制的正文长度比如“d3af8”此时后面的2个空格是没有的,这样我也可以计算到长度并处理。
但有时候则是完全无意义的数字,真是搞不懂。不过浏览器倒是完全可以处理这种情况,不知道是如何处理的。我看了HTTP的RFC但是找不到,或者哪位仁兄发来详细的HTTP RFC文档。
解决方案 »
- 如何取得数据库中的随机N条纪录?
- 如何实现1-10中选择有条件的3个数字?在线等
- 跟大家探讨关于权限管理设计的问题
- 急,关于string和array的转化,在线等!
- 如何用listview实现类资源管理器的功能
- 谁能帮我?谁能?
- 用SQL语句中的ORDER BY如何排序两个字段的联合结果?
- Delphi6的注册码谁有
- 急! 关于 B/S 结构的问题。。。高手请指教
- paradox表日期型字段怎么引用
- 如何将一个控件设置为不可覆盖。我的TShape控件老是TLabel控件覆盖,有没有办法设置TShape控件的级别高于TLabel
- 我想在Form_Close事件中用Initialization节却出现“Statement expected but 'INITIALIZATION' found”错误
{ SOCKET Socket = ((SOCKET )((void **)pParam)[0]);
char *pHtmlBuf = (char *)((void **)pParam)[1];
int nHtmlBufLen = (int)((void **)pParam)[2];
CString *pCookie = (CString *)((void **)pParam)[3];
CEvent *pCreateRecvChunkedEvent = (CEvent *)((void **)pParam)[4];
CEvent *pGetHtmlEvent = (CEvent *)((void **)pParam)[5];
pCreateRecvChunkedEvent->SetEvent(); // 接收HTTP头信息
char szRecvBuf[2048]={0};
int nRecvLen = 0; // 找HTTP头的结尾
while(true)
{
int nTmpRecvLen = recv(Socket,(char *)szRecvBuf+nRecvLen,sizeof(szRecvBuf),0);
// 错误,悲观处理
if (nTmpRecvLen < 1)
break;
nRecvLen += nTmpRecvLen; // 找http头的结尾
char *pHtmlPack = strstr(szRecvBuf, "\r\n\r\n");
if(pHtmlPack != NULL)
{
/*
// 找cookie
int nContentLength = {0};
for (int nCurParse = 0;nCurParse < pHtmlPack-szRecvBuf;)
{
// 取出当前行
char szCurLineData[2048] = {0};
char *pEol = strstr(szRecvBuf+nCurParse, "\r\n") + strlen("\r\n");
int nCurLineLen = pEol - (szRecvBuf+nCurParse);
memcpy(szCurLineData, szRecvBuf+nCurParse, nCurLineLen);
nCurParse += nCurLineLen; CString strCurLineData;
strCurLineData = szCurLineData;
strCurLineData.MakeLower();
if (pCookie!=NULL)
if (strncmp("set-cookie: " , strCurLineData, strlen("set-cookie: ")) == 0)
{
char szCookie[128] = {0};
memcpy(szCookie, szCurLineData+strlen("set-cookie: "), strstr(szCurLineData, ";")-szCurLineData-strlen("set-cookie: "));
*pCookie = szCookie;
} } //*/ // 求HTTP包内html数据开始位置
pHtmlPack += strlen("\r\n");
memcpy(szRecvBuf, pHtmlPack, (szRecvBuf+nRecvLen) - pHtmlPack);
memset(szRecvBuf + ((szRecvBuf+nRecvLen) - pHtmlPack), 0, pHtmlPack-szRecvBuf);
nRecvLen = (szRecvBuf+nRecvLen) - pHtmlPack;
break;
}
} // HTTP包长总度
int nHtmlPackLen = 0;
// 当前包还需要多少数据
int nHtmlPackNeedLen = 0;
// 接收HTTP中的HTML包一直到最后一个长度为0的包
do
{
// 当前HTTP包内的HTML数据位置
char *pHtmlPack = szRecvBuf;
// 处理一个段数据
// 数据已Chunked编码所以需要还原
// ,Chunked包结构类似[长度][数据......][长度][数据......][长度][数据......]
do
{
if (nHtmlPackNeedLen < 1) // 说明是一个Chunked新包
{
pHtmlPack = strstr(szRecvBuf+strlen("\r\n"), "\r\n");
if (pHtmlPack != NULL)
{
// 取得包长度 pHtmlPack += strlen("\r\n"); char szHtmlPackLen[32] = {0};
memcpy(szHtmlPackLen, szRecvBuf, pHtmlPack - szRecvBuf);
sscanf(szHtmlPackLen, "%x", &nHtmlPackLen); nHtmlPackNeedLen = nHtmlPackLen;
}
else
{
// 该段数据长度不够,无法取出长度,继续接收.
break;
}
}
else
{
// 将数据取出给返回数据的缓冲
CString strHtmlPackBuf;
if (nHtmlPackNeedLen < szRecvBuf+nRecvLen - pHtmlPack) // 需要的数据小于现在包内的数据,说明该包数据都在当前数据段(nRecvBuf)内
strHtmlPackBuf.GetBufferSetLength(nHtmlPackNeedLen);
else // 现有数据不够需要数据,现有多少给多少
strHtmlPackBuf.GetBufferSetLength(szRecvBuf+nRecvLen - pHtmlPack);
memcpy(strHtmlPackBuf.GetBuffer(strHtmlPackBuf.GetLength()
), pHtmlPack, strHtmlPackBuf.GetLength());
strncat(pHtmlBuf, strHtmlPackBuf.GetBuffer(0), nHtmlBufLen);
// 将得到的数据从接收buf(szRecvBuf)中删除(提前)
memcpy(szRecvBuf, pHtmlPack+strHtmlPackBuf.GetLength(), (szRecvBuf+nRecvLen)-(pHtmlPack+strHtmlPackBuf.GetLength()));
nRecvLen = szRecvBuf+nRecvLen-(pHtmlPack+strHtmlPackBuf.GetLength());
memset(szRecvBuf+nRecvLen, 0, sizeof(szRecvBuf)-nRecvLen);
nHtmlPackNeedLen -= strHtmlPackBuf.GetLength();
}
}while(nRecvLen > 0 && nHtmlPackLen>0); // 当szRecvBuf有数据未处理时 int nTmpRecvLen = recv(Socket, szRecvBuf+nRecvLen, sizeof(szRecvBuf)-nRecvLen, 0);
if (nTmpRecvLen > 0)
nRecvLen += nTmpRecvLen;
else
break; }while(nHtmlPackLen > 0 || nRecvLen > 0);//*/
pGetHtmlEvent->SetEvent(); return 0;
}
//取得正文内容,包含Chunked部分
ChunkStr:=Copy(RecvBuffer,Pos(#13#10#13#10,RecvBuffer)+4,Length(RecvBuffer));
RecvBuffer:='';
ChunkIndex:=1;
While ChunkIndex<Length(ChunkStr) do begin
//取得一个Chunk
TempStr:=Copy(ChunkStr,ChunkIndex,Pos(#13#10,ChunkStr)-1);
if TryStrToInt('$'+Trim(TempStr),Len) then begin //使用Trim是因为有些时候TempStr后面有一个空格
if Len=0 then Break;
//计主体内容
RecvBuffer:=RecvBuffer+Copy(ChunkStr,ChunkIndex+Length(TempStr)+2,Len);
end;
ChunkIndex:=ChunkIndex+Length(TempStr)+2+Len+2;
end;如果代码有什么不足,或没有预料到的错误请指出 谢谢