流错误:在上一次调用退出之前再次调用InternetSetStatusCallback

问题描述 投票:0回答:1

我正在使用InternetSetStatusCallback来传输数据:

CallbackPointer = InternetSetStatusCallback(SessionHandle,
    (INTERNET_STATUS_CALLBACK)CallBack);

尽管流量数据每250ms发送一次,但有时会在退出之前再次调用下面的CallBack函数,因此程序应该有足够的时间来处理数据。

bool InsideFunc = false;

VOID CALLBACK
CallBack(
__in HINTERNET hInternet,
__in DWORD_PTR dwContext,
__in DWORD dwInternetStatus,
__in_bcount(dwStatusInformationLength) LPVOID lpvStatusInformation,
__in DWORD dwStatusInformationLength
)
{
    if (InsideFunc)
    {
            // should not happen
    }
    InsideFunc = true;

    cOandaFeed* oandaFeed = (cOandaFeed*)dwContext;
    ASSERTRETURN(oandaFeed);

    ASSERT(dwContext);

    switch (dwInternetStatus) {
    case INTERNET_STATUS_HANDLE_CREATED:
        oandaFeed->StatusHandle = lpvStatusInformation;
        break;
    case INTERNET_STATUS_REQUEST_COMPLETE:
        if (oandaFeed->State == cOandaFeed::OPENING)
            oandaFeed->StartFeeding();
        break;
    case INTERNET_STATUS_RESPONSE_RECEIVED:
        if (oandaFeed->State == cOandaFeed::FEEDING) {
            oandaFeed->ReadFile(); // this is where I call InternetReadFileEx
            oandaFeed->CollectAndForwardChunks();
        }
        break;
    case INTERNET_STATUS_HANDLE_CLOSING:
        oandaFeed->SetState(cOandaFeed::IDLE);
        break;
    case INTERNET_STATUS_RECEIVING_RESPONSE:
        break;
    }

    InsideFunc = false;
}

因此程序正确初始化并获得INTERNET_STATUS_RECEIVING_RESPONSE和INTERNET_STATUS_RESPONSE_RECEIVED等状态响应。到现在为止还挺好。但是下一次迭代出错了,InternetReadFileEx调用两次并获取错误消息,一个用于挂起的IO,另一个用于InternetReadFileEx的内部错误。下一轮再好,然后是错误。

我做了“bool insideFunc”技巧,看看我怀疑是否正在发生什么,是的,有时候“调用”在设置之前是真的,所以有时它甚至在它结束之前被调用。我只想在INTERNET_STATUS_RESPONSE_RECEIVED上阅读我的消息,但有时CallBack()会在它完成之前再次被调用,并且InternetReadFileEx会在错误的时间发生,导致它返回错误代码997和12004。

我该如何解决?

c++ http winapi https
1个回答
0
投票

我能够很容易地解决这个问题。问题是我在交换机的INTERNET_STATUS_RESPONSE_RECEIVED情况下保持了我的ReadFile()调用。它导致了麻烦,因为在我的ReadFile()内部调用InternetReadFileEx()时,通过回调发送状态,导致再次对ReadFile()进行递归调用。

因此,第一个ReadFile()调用导致997:ERROR_IO_PENDING,而第二个调用(导致但递归)导致12004:内部错误。

解决方案:在我将ReadFile()移动到交换机中的INTERNET_STATUS_REQUEST_COMPLETE情况后,我只得到了ERROR_IO_PENDING,因为我们没有在ReadFile()中获得具有此状态的CallBack。在InternetReadFileEx()返回很久之后,我们异步地获得此状态。 ERROR_IO_PENDING是正常的:

注意GetLastError代码ERROR_IO_PENDING不是失败;它指定读取操作异步完成等待完成。

引自qazxsw poi

流媒体工作

  1. 调用InternetReadFileEx()
  2. 它返回一个待处理的IO
  3. 当它有新数据(价格)时,它只是通过INTERNET_STATUS_REQUEST_COMPLETE发送它异步。
  4. 如果几秒内没有任何数据(没有价格变化),它只会通过INTERNET_STATUS_REQUEST_COMPLETE发送心跳以避免超时。
  5. 收到数据后,我再次立即调用InternetReadFileEx()(参见#1)

这是流媒体在Oanda的工作方式,但我想这是常见的做法?

谢谢大家的回复。

© www.soinside.com 2019 - 2024. All rights reserved.