Winsock2 spi截取网页数据,网页数据是截取下来了,但IE出错

jilei08124 2009-09-14 11:45:29
我用《WINDOWS网络编程技术》里的PacketCapture代码,在WSPrecv函数里加了截取网页数据程序,网页数据是截取下来了,但打开网页时,IE出错
请各位大虾帮帮忙!!!!!!!!!
...全文
190 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
jilei08124 2009-09-14
  • 打赏
  • 举报
回复
typedef struct
{
int find_header;
int find_gzip;
int find_ContentLen;
int find_chunkd;
int first;
}header;
typedef struct
{
int chunk_end;
int chunk_curlen;
}chunked;
typedef struct
{
int number;
header head;
chunked chunk;
long totallen;
long currlen;
WSABUF WebSourceBuffer;
}ArrayWeb;
ArrayWeb arry = {0, {-1,-1,-1,-1,-1},{-1, 0},0,0,{0}};
jilei08124 2009-09-14
  • 打赏
  • 举报
回复
int WSPAPI WSPRecv(
SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesRecvd,
LPDWORD lpFlags,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
LPWSATHREADID lpThreadId,
LPINT lpErrno
)
{
ODS(_T("WSPRecv ..."));

BOOL IsSetCompletionRoutine = FALSE;
if(lpOverlapped && lpCompletionRoutine && m_Overlapped.AddOverlapped(s
, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags
, lpOverlapped, lpCompletionRoutine, NULL, NULL, 0/*WSPRecv*/)
)
{
OutputDebugString(" ==>WSPRecv WSA_IO_PENDING\n");
lpCompletionRoutine = CompletionRoutine;
IsSetCompletionRoutine = TRUE;
}

int iRet = NextProcTable.lpWSPRecv(s, lpBuffers, dwBufferCount
, lpNumberOfBytesRecvd, lpFlags, lpOverlapped
, lpCompletionRoutine, lpThreadId, lpErrno);

WSABUF tmpBuffer;
for (int i = 0; i < (int)dwBufferCount; i++)
{
CString tmpString;
tmpString.Format("%s", lpBuffers[i].buf);
OutputDebugString("\n**************************************************\n");
OutputDebugString(tmpString);
OutputDebugString("\n**************************************************\n");

tmpBuffer.len = *lpNumberOfBytesRecvd;
tmpBuffer.buf = (char *)malloc(tmpBuffer.len);
memcpy(tmpBuffer.buf, lpBuffers[i].buf, tmpBuffer.len);

char *lpfront = NULL;
int point_front_len = 0;
if(arry.head.find_header == -1)
{
HandleHttpHeader(tmpBuffer, lpfront, point_front_len);
if (arry.totallen > 0)
{
lpfront = tmpBuffer.buf + ((int)tmpBuffer.len - point_front_len);
HandleHContentlenWeb(lpfront, point_front_len, tmpBuffer.buf, tmpBuffer.len);
}
else
{
if (arry.head.find_chunkd > 0)
{
lpfront = tmpBuffer.buf + ((int)tmpBuffer.len - point_front_len);
HandleChunkWeb(lpfront, point_front_len,tmpBuffer.buf, tmpBuffer.len);
}
}

}
else
{
if (arry.totallen > 0 && arry.head.find_chunkd < 0)
{
Sleep(50);
HandleHContentlenWeb(lpfront, point_front_len, tmpBuffer.buf, tmpBuffer.len);
}
else
{
if (arry.head.find_chunkd > 0)
{
Sleep(50);
HandleChunkWeb(lpfront, point_front_len,tmpBuffer.buf, tmpBuffer.len);
}
}
}
if (tmpBuffer.len > 0)
{
free(tmpBuffer.buf);
tmpBuffer.len = 0;
}

}

PrintReturnCode(iRet, lpErrno);

if(iRet == SOCKET_ERROR || IsSetCompletionRoutine == TRUE)
return iRet;

PrintSocket(s, *lpNumberOfBytesRecvd, "WSPRecv");

return iRet;
}
jilei08124 2009-09-14
  • 打赏
  • 举报
回复
/* HTTP gzip decompress */
int httpgzdecompress(Byte *zdata, uLong nzdata,
Byte *data, uLong *ndata)
{
int err = 0;
z_stream d_stream = {0}; /* decompression stream */
static char dummy_head[2] =
{
0x8 + 0x7 * 0x10,
(((0x8 + 0x7 * 0x10) * 0x100 + 30) / 31 * 31) & 0xFF,
};
d_stream.zalloc = (alloc_func)0;
d_stream.zfree = (free_func)0;
d_stream.opaque = (voidpf)0;
d_stream.next_in = zdata;
d_stream.avail_in = 0;
d_stream.next_out = data;
if(inflateInit2(&d_stream, 47) != Z_OK) return -1;
while (d_stream.total_out < *ndata && d_stream.total_in < nzdata) {
d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
if((err = inflate(&d_stream, Z_NO_FLUSH)) == Z_STREAM_END) break;
if(err != Z_OK )
{
if(err == Z_DATA_ERROR)
{
d_stream.next_in = (Bytef*) dummy_head;
d_stream.avail_in = sizeof(dummy_head);
if((err = inflate(&d_stream, Z_NO_FLUSH)) != Z_OK)
{
return -1;
}
}
else return -1;
}
}
if(inflateEnd(&d_stream) != Z_OK) return -1;
*ndata = d_stream.total_out;
return 0;
}


/*void writelog(char *ch)
{
FILE *file;
file = fopen("c:\\log.txt","a+");
if (file)
{
fprintf(file,"error:%s\n",ch);
fclose(file);
}
}*/
void WriteGzip(
char *buffer,
int Content_Length
)
{
FILE *file;
file = fopen("c:\\gzip.gzip","ab+");
if (file)
{
fwrite(buffer,1,Content_Length,file);
fclose(file);
}
}

void Initial()
{
free(arry.WebSourceBuffer.buf);
arry.WebSourceBuffer.len = 0;
//arry = {0, {-1,-1,-1,-1,-1},{-1, 0},0,0,{0}};
arry.head.find_header = -1;
arry.head.find_gzip = -1;
arry.head.find_ContentLen = -1;
arry.head.find_chunkd = -1;
arry.head.first = -1;
arry.chunk.chunk_curlen = 0;
arry.chunk.chunk_end = -1;
arry.totallen = 0;
arry.currlen = 0;
}

void SaveWebSource(char *buffer, int Content_Length)
{
if (buffer != NULL)
{
FILE *file;
if (arry.head.find_gzip == -1)
{
file = fopen("c:\\WebSource_txt.txt","w");
}
else
{
file = fopen("c:\\WebSource.gzip","wb");
}
if (file)
{
fwrite(buffer,1,Content_Length,file);
fclose(file);

//char szMsg[120];

//sprintf(szMsg, "Content_Length=%d", Content_Length);
//MessageBox(0, szMsg, "MSG", 0);
}

if (arry.head.find_gzip >= 0)
{
//解压gzip文件
Bytef *odata = (unsigned char *)malloc(1024*1024);
uLong nodata = 1024*1024;

int uncompr_return = httpgzdecompress((unsigned char *)buffer,
Content_Length, odata, &nodata);
if(uncompr_return == 0)
{
FILE *file_degz = fopen("C:\\WebSource.txt", "w");
fwrite(odata, 1, nodata, file_degz);
fclose(file_degz);
}
free(odata);
}
}
}
int HandleHContentlenWeb(
char *lpfront,
int point_front_len,
//WSABUF tmpBuffer
char *tmpBuffer_buf,
DWORD tmpBuffer_len
)
{
if (arry.head.first == 1)
{
//Sleep(20);// 为什么只有加断点时,大的网页才能截取正确
if (arry.totallen < arry.currlen + point_front_len)
{
memcpy(arry.WebSourceBuffer.buf + arry.currlen, lpfront, arry.totallen - arry.currlen);
arry.currlen = arry.totallen;
//WriteGzip(lpfront, point_front_len);
}
else
{
memcpy(arry.WebSourceBuffer.buf + arry.currlen, lpfront, point_front_len);
arry.currlen += point_front_len;
//WriteGzip(lpfront, point_front_len);
}
arry.head.first = 0;
}
else
{
if (arry.totallen < arry.currlen + (int)tmpBuffer_len)
{
memcpy(arry.WebSourceBuffer.buf + arry.currlen, tmpBuffer_buf, arry.totallen - arry.currlen);
arry.currlen = arry.totallen;
//WriteGzip(tmpBuffer_buf, arry.totallen - arry.currlen);
}
else
{
memcpy(arry.WebSourceBuffer.buf + arry.currlen, tmpBuffer_buf, tmpBuffer_len);
arry.currlen += tmpBuffer_len;
//WriteGzip(tmpBuffer_buf, tmpBuffer_len);
}
}

if (arry.currlen == arry.totallen && arry.totallen > 0)
{
DWORD dwStart = 0;
DWORD dwEnd = 0;
dwStart = GetTickCount();
SaveWebSource(arry.WebSourceBuffer.buf,arry.totallen);
dwEnd = GetTickCount();
DWORD UseTime = dwEnd - dwStart;
Initial();
}
//OutputDebugString("\n______________________---NULL---___________________________\n");

return 0;
}

int HandleChunkWeb(
char *lpfront,
int point_front_len,
char *tmpBuffer_buf,
DWORD tmpBuffer_len
//WSABUF tmpBuffer
)
{
CString tmpString;
int Content_Length = 0;

if (arry.head.first == 1)
{
int tmpString_len = 0;
PCHAR chunk_endchar = "\r\n\r\n";
char *pdest = NULL;
while (tmpString_len < point_front_len)
{
tmpString = lpfront + tmpString_len;
arry.chunk.chunk_end = tmpString.Find(chunk_endchar);
pdest = strstr(tmpBuffer_buf + tmpString_len, chunk_endchar);
if (arry.chunk.chunk_end == -1)
{
tmpString_len += strlen(tmpString) + 1;
}
else
{
break;
}
}
if (arry.chunk.chunk_end >= 0)
{
int chunk_endlen = pdest - lpfront + 1 + 4;
memcpy(arry.WebSourceBuffer.buf + arry.chunk.chunk_curlen, lpfront, chunk_endlen);
arry.chunk.chunk_curlen += chunk_endlen;
}
else
{
memcpy(arry.WebSourceBuffer.buf + arry.chunk.chunk_curlen, lpfront,point_front_len);
arry.chunk.chunk_curlen += point_front_len;
}
arry.head.first = 0;

}
else
{
int tmpString_len = 0;
PCHAR chunk_endchar = "\r\n\r\n";
char *pdest = NULL;
while (tmpString_len < (int)tmpBuffer_len)
{
tmpString = tmpBuffer_buf + tmpString_len;
arry.chunk.chunk_end = tmpString.Find(chunk_endchar);
pdest = strstr(tmpBuffer_buf + tmpString_len, chunk_endchar);
if (arry.chunk.chunk_end == -1)
{
tmpString_len += strlen(tmpString) + 1;
}
else
{
break;
}
}

if (arry.chunk.chunk_end >= 0)
{
int chunk_endlen = pdest - tmpBuffer_buf + 1 + 4;
memcpy(arry.WebSourceBuffer.buf + arry.chunk.chunk_curlen, tmpBuffer_buf, chunk_endlen);
arry.chunk.chunk_curlen += chunk_endlen;
}
else
{
memcpy(arry.WebSourceBuffer.buf + arry.chunk.chunk_curlen, tmpBuffer_buf, tmpBuffer_len);
arry.chunk.chunk_curlen += tmpBuffer_len;
}

}
if (arry.chunk.chunk_end >= 0)
{
char chunk_head[10];
memset(chunk_head, 0x0, sizeof(chunk_head));
memcpy(chunk_head, arry.WebSourceBuffer.buf, sizeof(chunk_head));

char *p=strstr(chunk_head, "\r\n");
if (p)
{
char *stopstr = "\r\n";
int chunk_size = strtol(chunk_head,&stopstr,16);

WSABUF chunk_data;
chunk_data.buf = (char *)malloc(2*1024*1024);
chunk_data.len = 2*1024*1024;

char *chunk_point = arry.WebSourceBuffer.buf;
while (chunk_size > 0)
{
chunk_point = strstr(chunk_point, "\r\n");
chunk_point += 2;
memcpy(chunk_data.buf + Content_Length,chunk_point,chunk_size);
chunk_point += chunk_size;
chunk_point += 2;
Content_Length += chunk_size;

memset(chunk_head, 0x0, sizeof(chunk_head));
memcpy(chunk_head, chunk_point, sizeof(chunk_head));

p = strstr(chunk_head, "\r\n");
if (p)
{
char *stopstr = "\r\n";
chunk_size = strtol(chunk_head,&stopstr,16);
}
else
{
break;
}
}

SaveWebSource(chunk_data.buf,Content_Length);
free(chunk_data.buf);
chunk_data.len = 0;
Initial();
}
}
return 0;
}
int HandleHttpHeader(
WSABUF tmpBuffer,
char *lpfront,
int &point_front_len
)
{
int find_http0 = -1;
int find_http1 = -1;

PCHAR HTTP_1 = "HTTP/1.1 200 OK";
PCHAR HTTP_0 = "HTTP/1.0 200 OK";
PCHAR chunkd = "chunked";
PCHAR gzip = "gzip";
PCHAR Content_Length = "Content-Length: ";

CString tmpString;
tmpString.Format("%s", tmpBuffer.buf);
find_http0 = tmpString.Find(HTTP_0);
find_http1 = tmpString.Find(HTTP_1);

if ((find_http0 >= 0) || (find_http1 >= 0))
{
arry.head.find_gzip = tmpString.Find(gzip);
arry.head.find_ContentLen = tmpString.Find(Content_Length);
arry.head.find_chunkd = tmpString.Find(chunkd);

arry.head.find_header = 1;
arry.head.first = 1;
}
else
{
return 1;
}

//将数据体的长度读入arry.totallen中
if (arry.head.find_ContentLen >= 0)
{
char *pdest = NULL;
int result = 0;

pdest = strstr(tmpBuffer.buf,Content_Length);
result = pdest - tmpBuffer.buf + 1 + 15;
char *point_1 = tmpBuffer.buf + result;

char s[100] = {0};
int k = 0;

while (*point_1 != '\r')
{
s[k] = *point_1;
point_1++;
k++;
}
arry.totallen = atoi(s);
arry.WebSourceBuffer.len = arry.totallen;
arry.WebSourceBuffer.buf = (char *)malloc(arry.totallen);

//CString st;
//st.Format("\n////////////////////////////////////////////////%d\n",arry.totallen);
//OutputDebugString(st);
}
else
{
if (arry.head.find_chunkd >= 0)
{
arry.WebSourceBuffer.len = 1024*1024;
arry.WebSourceBuffer.buf = (char *)malloc(1024*1024);
}
}

if ((find_http0 >= 0) || (find_http1 >= 0))
{
//获得文件数据的开始指针lpfront
int find_front = -1;
PCHAR Front = "\r\n\r\n";
int Front_len = (int)tmpBuffer.len;
int head_len = 0;

char *pdest = NULL;
if (((find_http0 >= 0) || (find_http1 >= 0)))
{
tmpString.Format("%s",tmpBuffer.buf);
find_front = tmpString.Find(Front);


if (find_front >= 0)
{
pdest = strstr(tmpBuffer.buf,Front);
head_len = pdest - tmpBuffer.buf + 1 + 3;
lpfront = tmpBuffer.buf + head_len;
}

}
point_front_len = Front_len - head_len;

}
return 0;

}


CoderOfVC 2009-09-14
  • 打赏
  • 举报
回复
调试一下看在哪一步出错。而且你没发代码人家也帮不了你。。

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧