gpt4 book ai didi

c - InternetReadFileEx 给出 10035 和 1008 错误

转载 作者:行者123 更新时间:2023-11-30 15:47:48 25 4
gpt4 key购买 nike

我正在尝试编写一个异步 Wininet 应用程序。我在 INTERNET_STATUS_REQUEST_COMPLETE 的情况下读取回调函数中的数据,并处理 ERROR_IO_PENDING 错误。但是从互联网读取一些数据后,InternetReadFileEx 函数给出了 10035=WSAEWOULDBLOCK (非阻塞套接字操作无法立即完成)错误。发生该错误后,我再次调用 InternetReadFileEx,这次它给出 1008=ERROR_NO_TOKEN (尝试引用不存在的 token 。) 错误。我认为我的设计不正确,因此我收到了这些错误。

这是我的代码片段:

    case INTERNET_STATUS_REQUEST_COMPLETE:
{
BOOL bAllDone= FALSE;
DWORD lastError;

do
{
//Create INTERNET_BUFFERS
char m_pbReadBuffer[4096];
INTERNET_BUFFERS BuffersIn;
ZeroMemory(&BuffersIn, sizeof(INTERNET_BUFFERS));
BuffersIn.dwStructSize = sizeof(INTERNET_BUFFERS);
BuffersIn.lpvBuffer = m_pbReadBuffer;
BuffersIn.dwBufferLength = 4096;

InternetReadFileEx(ReqContext->File, &BuffersIn, IRF_ASYNC, 1);

//HERE I GOT THOSE 10035 and 1008 ERRORS
lastError = GetLastError();

if(lastError == 997) // handling ERROR_IO_PENDING
break;//break the while loop

//append it to my ISTREAM
(ReqContext->savedStream)->Write(BuffersIn.lpvBuffer, BuffersIn.dwBufferLength, NULL);

if (BuffersIn.dwBufferLength == 0)
bAllDone = TRUE;

}while(bAllDone == FALSE);

//delete[] m_pbReadBuffer;

if(bAllDone == TRUE && lastError== 0)
{
//these are for passing the ISTREAM to the function which calls "InternetOpenUrl"
LARGE_INTEGER loc;
loc.HighPart = 0;
loc.LowPart = 0;
ReqContext->savedStream->Seek(loc, STREAM_SEEK_SET, NULL);
ReqContext->savedCallback->OnUrlDownloaded(S_OK, ReqContext->savedStream); //Tell silverlight ISTREAM is ready
ReqContext->savedStream->Release();
ReqContext->savedCallback->Release();

InternetCloseHandle(ReqContext->File);
InternetSetStatusCallback(ReqContext->Connection, NULL);
InternetCloseHandle(ReqContext->Connection);
delete[] ReqContext;
}
}
break;

有人可以帮助我纠正这个问题吗?感谢大家的帮助...

最佳答案

GetLastError() 仅当 InternetReadFileEx()(或任何其他 API)实际上因错误而失败时才有意义。否则,您将处理早期 API 调用中的错误,从而使您的代码产生错误的错觉,认为错误发生了,而实际上可能没有发生错误。您必须注意 API 返回值,但您当前忽略了 InternetReadFileEx() 的返回值。

更糟糕的是,您在异步模式下使用 InternetReadFileEx(),但使用的是 INTERNET_STATUS_REQUEST_COMPLETE 回调处理程序本地的接收缓冲区。如果 InternetReadFileEx() 失败并出现 ERROR_IO_PENDING 错误,则读取将在后台执行,并且在读取完成时将触发 INTERNET_STATUS_REQUEST_COMPLETE。但是,当发生该错误时,您将中断循环(即使读取仍在进行中),并且该缓冲区将在读取完成之前超出范围。当读取仍在进行时,接收缓冲区仍在堆栈上,并且 InternetReadFileEx() 仍在写入它,但它可能会同时重新用于其他用途,因为您的代码没有等待阅读完成就继续做其他事情。

您需要重新考虑您的方法。要么:

  1. 删除 IRF_ASYNC 标志,因为这就是其余回调代码期望 InternetReadFileEx() 的行为方式。

  2. 重新编写代码以正确在异步模式下运行。动态分配接收缓冲区(或者至少将其存储在异步读取期间保留在范围内的其他位置),不要调用 IStream::Write() 除非您实际上有数据要写入(仅当InternetReadFileEx() 立即返回 TRUE,或者您收到 INTERNET_STATUS_REQUEST_COMPLETE 事件,其中包含先前 InternetReadFileEx()/ERROR_IO_PENDING 的成功代码 调用)等

有大量在线示例和教程展示如何在异步模式下使用 InternetReadFileEx()。四处搜寻。

关于c - InternetReadFileEx 给出 10035 和 1008 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17215489/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com