C InternetReadFileEx给出10035和1008错误

C InternetReadFileEx给出10035和1008错误,c,winapi,wininet,C,Winapi,Wininet,我正在尝试编写一个异步Wininet应用程序。我读取回调函数中的数据,以防INTERNET_STATUS_REQUEST_COMPLETE,并处理错误_IO_未决错误。但在从internet读取一些数据后,InternetReadFileEx函数给我10035=WSAEWOULDBLOCK(非阻塞套接字操作无法立即完成)错误。在那个错误之后,我再次调用InternetReadFileEx,这次它给了我1008=error\u NO\u令牌(试图引用一个不存在的令牌)。我认为我的设计不正确,因此我

我正在尝试编写一个异步Wininet应用程序。我读取回调函数中的数据,以防INTERNET_STATUS_REQUEST_COMPLETE,并处理错误_IO_未决错误。但在从internet读取一些数据后,InternetReadFileEx函数给我10035=WSAEWOULDBLOCK(非阻塞套接字操作无法立即完成)错误。在那个错误之后,我再次调用InternetReadFileEx,这次它给了我1008=error\u NO\u令牌(试图引用一个不存在的令牌)。我认为我的设计不正确,因此我收到了这些错误

以下是我的代码片段:

    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()
,但您使用的是
internetstatus\u REQUEST\u COMPLETE
回调处理程序本地的接收缓冲区。如果
InternetReadFileEx()
失败并出现
错误\u IO\u挂起
错误,则在后台执行读取,读取完成时将触发
互联网状态请求\u完成
。但是,当该错误发生时,您正在中断循环(即使读取仍在进行),并且该缓冲区将在读取完成之前超出范围。当读取仍在进行时,接收缓冲区仍在堆栈上,并且
InternetReadFileEx()
仍在向其写入,但它可能同时被重新用于其他事情,因为您的代码继续执行其他事情,并且没有等待读取完成

你需要重新思考你的方法。要么:

  • 删除
    IRF\u ASYNC
    标志,因为回调代码的其余部分都希望
    InternetReadFileEx()
    这样做

  • 重新编写代码以在异步模式下正确运行。动态分配接收缓冲区(或至少将其存储在异步读取期间保留在作用域中的其他位置),除非您实际有数据要写入,否则不要调用
    IStream::Write()
    (仅当
    InternetReadFileEx()时)
    立即返回TRUE,或者您会收到一个
    INTERNET\u STATUS\u REQUEST\u COMPLETE
    事件,其中包含来自早期
    InternetReadFileEx()
    /
    ERROR\u IO\u PENDING
    调用)的成功代码,等等

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