有谁了解异步读取InternetReadFileEx()?

shines77 2003-03-09 09:08:58
我使用异步方式InternetReadFileEx()读取,代码如下:

INTERNET_BUFFERS ib;
memset(&ib, 0, sizeof(INTERNET_BUFFERS));
ib.dwStructSize = sizeof(INTERNET_BUFFERS);
ib.lpvBuffer = (void *)pRecvBuffer;
ib.dwBufferLength = BUFFER_SIZE; // BUFFER_SIZE=1024
ib.dwBufferTotal = dwBufferTotal;
//******* 我临时加的 *******
ib.dwOffsetLow = 0;
ib.dwOffsetHigh = (dwBufferTotal==0) ? 0 : (dwBufferTotal-1);
//******* 我临时加的 *******

bOk = TRUE;
//while( bOk && ib.dwBufferLength!=0 )
//文件大于>4096左右的时候没必要循环的,
//正常的话应该等待回调收到下一次的INTERNET_STATUS_REQUEST_COMPLETE消息
//这里加循环适用于在文件较小的时候,可是我该怎么判断,什么时候要在这while循环?
//这就是我纳闷的地方
{
//Start the pump
TRACE("\n>>>>> Start the pump()...\n");
bOk = ::InternetReadFileEx( m_hHttpFile, &ib, IRF_ASYNC, dwContext );
if(!bOk && GetLastError()==ERROR_IO_PENDING)
{
// wait for next complete
(*pRequestCompleteID)++;
TRACE1(">>>>> Set nRequestCompleteID=%d.\n", *pRequestCompleteID);
}
else
{
if(bOk)
{
TRACE(">>>>> Start Pump() intermit!!\n");
TRACE1(">>>>> InternetReadFileEx() : ==> %d.\n", bOk);
TRACE1(">>>>> GetLastError()==ERROR_IO_PENDING ? : ==> %d.\n",
(GetLastError()==ERROR_IO_PENDING));
TRACE1(">>>>> GetLastError() : ==> %d.\n", GetLastError());
TRACE1(">>>>> ib.dwBufferLength: %d\n", ib.dwBufferLength);
(*pRequestCompleteID)++;
TRACE1(">>>>> Set nRequestCompleteID=%d.\n", *pRequestCompleteID);
TRACE("\n");
}
else
{
TRACE(">>>>> Start Pump() error!!\n");
TRACE1(">>>>> InternetReadFileEx() : ==> %d.\n", bOk);
TRACE1(">>>>> GetLastError()==ERROR_IO_PENDING ? : ==> %d.\n",
(GetLastError()==ERROR_IO_PENDING));
TRACE1(">>>>> GetLastError() : ==> %d.\n", GetLastError());
*pRequestCompleteID = -1;
}
}
}

//正常的话应该只执行InternetReadFileEx()一次,返回值应该是False,
//GetLastError()应该等于ERROR_IO_PENDING。
//可是当URL文件为2890字节时,InternetReadFileEx()返回值为True, GetLastError()为0,但是偶尔有几次又不是:(
//怎么回事?我的读取缓冲区大小为1024。

谢谢。
...全文
323 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
dandyboy 2003-08-16
  • 打赏
  • 举报
回复
up
shines77 2003-04-25
  • 打赏
  • 举报
回复
给分都没有人啊
shines77 2003-03-09
  • 打赏
  • 举报
回复
原文参考:
http://www.codeproject.com/useritems/asyncwininet.asp

帮up一下
shines77 2003-03-09
  • 打赏
  • 举报
回复
InternetReadFileEx()异步读取返回True是什么意思,按我理解,
True是指读取指定长度缓冲区成功,异步应该立刻就返回,是有1024字节,
不会瞬间就完了吧,

不过我好像有的懂了,第一次也应该循环的,不应该分第一次和第一次以后的区别,
看来是我没有理解codeproject的文章的意思,我不知道该怎么写waiting部分,
我的方法很不好:

6&7&8 Read the remaining data in a loop

Use InternetReadFileEx with the IRF_ASYNC flag to read the remaining data asynchronously. Don’t use InternetReadFile since it is a synchronous function.
You must loop on InternetReadFileEx while the ib.dwBufferLength is not 0.
Before each iteration you must adjust the lpvBuffer pointer and reset the dwBufferLength members of ib: add the received length to the pointer and set dwBufferLength to your remaining buffer size.

//Start the pump
BOOL bOk = InternetReadFileEx( m_hHttpFile, &ib, IRF_ASYNC, (LPARAM)this );
if(!bOk && GetLastError()==ERROR_IO_PENDING)
wait...

//Pump
while( bOk && ib.dwBufferLength!=0 )
{
(adjust ib values)
bOk = InternetReadFileEx( m_hHttpFile, &ib, IRF_ASYNC, (LPARAM)this );
if(!bOk && GetLastError()==ERROR_IO_PENDING)
wait...
}

Your callback should receive these notifications (maybe more than once):
[connect] InternetStatus: 40 (receiving response)
[connect] InternetStatus: 41 (response received)
[connect] InternetStatus: 50
[connect] InternetStatus: 51
and maybe [connect] InternetStatus: 100 INTERNET_STATUS_REQUEST_COMPLETE

The lattest is received only if GetLastError() returned ERROR_IO_PENDING.

If you stored the total data size (in bytes) in the dwBufferTotal member, use it to set the final “0” in your string buffer (if it’s a string).
buf[ib.dwBufferTotal] = 0;

18,356

社区成员

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

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