InternetSetStatusCallback设置的回调函数中dwInternetStatus一直在回传   ,并在两种状态 
  INTERNET_STATUS_RECEIVING_RESPONSE   和   INTERNET_STATUS_RESPONSE_RECEIVED中切换 。 状态为INTERNET_STATUS_RESPONSE_RECEIVED时lpvStatusInformation的值一直为0。

解决方案 »

  1.   

    debugger attach进取看看,再做什么
      

  2.   

    你的描述没看出什么问题
    查看一下 hInternet是否有什么问题,多分析一些错误原因
      

  3.   

    回调函数所做的事
    void CALLBACK CAsynHttpClient::AsyncInternetCallback(HINTERNET hInternet,
                                                   DWORD dwContext,
                                                   DWORD dwInternetStatus,
                                                   LPVOID lpvStatusInformation,
                                                   DWORD dwStatusInformationLength)
    {
    CAsynHttpClient *pObj = (CAsynHttpClient*)dwContext;
    switch(dwInternetStatus)
    {
    case  INTERNET_STATUS_HANDLE_CREATED:
    /*if(NULL == pObj->m_hInternetConn)
    pObj->m_hInternetConn = (HINTERNET)(((LPINTERNET_ASYNC_RESULT)(lpvStatusInformation))->dwResult);
    else if(NULL == pObj->m_hFile)
    pObj->m_hFile = (HINTERNET)(((LPINTERNET_ASYNC_RESULT)(lpvStatusInformation))->dwResult);*/
       OnInternetHandleCreated(dwContext,(LPINTERNET_ASYNC_RESULT)lpvStatusInformation);
             break;
    case INTERNET_STATUS_HANDLE_CLOSING: ::SetEvent(pObj->m_hEvent[1]);  break;

    case  INTERNET_STATUS_REQUEST_COMPLETE:
    if(ERROR_SUCCESS==((LPINTERNET_ASYNC_RESULT)(lpvStatusInformation))->dwError)
    {
    //设置句柄被创建事件或者读数据成功完成事件
    ::SetEvent(pObj->m_hEvent[0]);
    }
    else
    {
    //如果发生错误,则设置子线程退出事件
    ::SetEvent(pObj->m_hEvent[2]);

    }
    break;
        case INTERNET_STATUS_RECEIVING_RESPONSE:
    break;
    case INTERNET_STATUS_RESPONSE_RECEIVED:
    DWORD *dwBytesReceived = (DWORD*)lpvStatusInformation;
    if(*dwBytesReceived ==0)
                pObj->bAllDone = TRUE;
    break; }
    }
      

  4.   

    获取html页面
    BOOL CAsynHttpClient::GetHttpFile(DWORD HttpReqType,CString m_szUrl,CString m_RefererURL,LPCSTR pPostDataBuf,DWORD dwPostSize,BOOL bSelfServer)
    {
       
    strRequestURL = m_szUrl;         //保存请求的资源URL
    CString strTempURL = m_szUrl;
    DWORD dwType = AFX_INET_SERVICE_HTTP;
    DWORD dwFlag = INTERNET_FLAG_NO_AUTO_REDIRECT|INTERNET_FLAG_RELOAD|INTERNET_FLAG_NO_CACHE_WRITE|INTERNET_FLAG_KEEP_CONNECTION;
    INTERNET_PORT wPort = 80;
    CString strServer = "", strObject ="";
    CString strHttpReqType = "";
        static int nJumCounts = 0;
    strHostURL = "http://";
    //判断是http还是https协议
    //strTempURL.MakeLower();
    int nLen = strTempURL.GetLength()+1;
    if(nLen > 0)
    {
    char* pstr = new char[nLen];
    if(pstr != NULL)
    {
    memset(pstr,0,nLen);
    memcpy(pstr,(char*)(LPCTSTR)strTempURL,nLen-1);
    strTempURL.ReleaseBuffer();
    errno_t err = _strlwr_s(pstr,nLen);
    if(err == 0)
    strTempURL = CString(pstr,nLen-1);
    delete[] pstr;
    pstr = NULL;
    } }
    if(strTempURL.Find("https://") ==0 )
    {
    strHostURL = "https://";
    dwType= AFX_INET_SERVICE_HTTPS;
    dwFlag |= INTERNET_FLAG_SECURE;
    }
       //解析服务地址
       AfxParseURL(m_szUrl,dwType,strServer,strObject,wPort);  
    m_szUrl.ReleaseBuffer();    strHostURL += strServer;                                   //保存主机地址主要是为了设置302跳转时设置Location的地址。
       if(!m_hInternet) return FALSE;
    // SetInternetStatusCallBack();
    //获取连接服务器句柄
    ::ResetEvent(m_hEvent[0]);
    ::ResetEvent(m_hEvent[1]);
    ::ResetEvent(m_hEvent[2]);
    m_hInternetConn = ::InternetConnect(m_hInternet,strServer,wPort,NULL,NULL,INTERNET_SERVICE_HTTP,INTERNET_FLAG_RELOAD,(DWORD)this);  
    if(NULL == m_hInternetConn)
    {
    if(ERROR_IO_PENDING == ::GetLastError())
    {
    DWORD dwRet = WaitExitEvent();
    if(dwRet != WAIT_OBJECT_0)
    {
    switch(dwRet)
    {
    case WAIT_OBJECT_0+1:
    ::ResetEvent(m_hEvent[1]);
    break;
    case WAIT_OBJECT_0+2:
    ::ResetEvent(m_hEvent[2]);
    break;
    }
    return FALSE;
    }
    ::ResetEvent(m_hEvent[0]);
    }
    else
    {
    return FALSE;
    }

    }
    //判断请求方法
    if(HttpReqType == HTTP_REQUEST_GET)
    {
    strHttpReqType = "GET";
    //判断GET是否有带参数
    if(pPostDataBuf != NULL && dwPostSize !=0)
    {
    CString strTemp = CString((char*)pPostDataBuf,dwPostSize);
    int index = strObject.Find("?");
    if( index != -1 )
    {
    //strObject  += "&";
    strObject  += strTemp;
    }
    else
    {
    strObject +="?";
    strObject +=strTemp ;
    }
    }
    }
    if(HttpReqType == HTTP_REQUEST_POST || HTTP_REQUEST_UPFILE == HttpReqType)
    strHttpReqType = "POST";
           //发送请求
    m_hRequest = ::HttpOpenRequest(m_hInternetConn,strHttpReqType,strObject,"HTTP/1.1",NULL,NULL,dwFlag,(DWORD)this);
    if(NULL == m_hRequest)
    {
    if(ERROR_IO_PENDING == ::GetLastError())
    {
    DWORD dwRet = WaitExitEvent();
    if(dwRet != WAIT_OBJECT_0)
    {
    switch(dwRet)
    {
    case WAIT_OBJECT_0+1:
    ::ResetEvent(m_hEvent[1]);
    break;
    case WAIT_OBJECT_0+2:
    ::ResetEvent(m_hEvent[2]);
    break;
    }
    return FALSE;
    }
    ::ResetEvent(m_hEvent[0]);
    }
    else
    {
    return FALSE;
    }

    }
    if(m_RefererURL == "")
    strRefererURL = m_szUrl;
    else if(m_RefererURL.CompareNoCase("null") != 0)
    strRefererURL = m_RefererURL;
    else
    strRefererURL = "";
        AddHeaders(bSelfServer);
    if(HttpReqType == HTTP_REQUEST_GET)
    {
    if(!::HttpSendRequestEx(m_hRequest,NULL,0,HSR_INITIATE,(DWORD)this))  //GET方式请求
    {
    if(ERROR_IO_PENDING == ::GetLastError())
    {
    DWORD dwRet = WaitExitEvent();
    if(dwRet != WAIT_OBJECT_0)
    {
    switch(dwRet)
    {
    case WAIT_OBJECT_0+1:
    ::ResetEvent(m_hEvent[1]);
    break;
    case WAIT_OBJECT_0+2:
    ::ResetEvent(m_hEvent[2]);
    break;
    }
    return FALSE;
    }
    ::ResetEvent(m_hEvent[0]);
    }
    else
    {
    return FALSE;
    }
    }
    }
    else if(HttpReqType == HTTP_REQUEST_POST || HttpReqType == HTTP_REQUEST_UPFILE)    //POST方式请求
    {
    again:
        INTERNET_BUFFERS BufferIn = {0};
    DWORD dwBytesWritten = 0;
    DWORD dwBytesWrittenTotal = 0;
    DWORD dwBytesRead = 0;
    int n;
    BYTE pBuffer[SENDBUFFERSIZE] = {0};
    BufferIn.dwStructSize = sizeof( INTERNET_BUFFERS ); // Must be set or error will occur
    BufferIn.Next = NULL; 
    if(HttpReqType == HTTP_REQUEST_POST)
    BufferIn.lpcszHeader = "Content-Type: application/x-www-form-urlencoded\r\n";
    else
    BufferIn.lpcszHeader = "Content-Type: multipart/form-data; boundary=---------------------------7d92de3850356\r\n";
    BufferIn.dwHeadersLength = strlen(BufferIn.lpcszHeader);
    BufferIn.dwHeadersTotal = 0;
    BufferIn.lpvBuffer = NULL;                
    BufferIn.dwBufferLength = 0;
    BufferIn.dwBufferTotal = dwPostSize; // This is the only member used other than dwStructSize
    BufferIn.dwOffsetLow = 0;
    BufferIn.dwOffsetHigh = 0; if(!::HttpSendRequestEx(m_hRequest,&BufferIn,0,HSR_INITIATE,(DWORD)this))  
    {
    if(ERROR_IO_PENDING == ::GetLastError())
    {
    DWORD dwRet = WaitExitEvent();
    if(dwRet != WAIT_OBJECT_0)
    {
    switch(dwRet)
    {
    case WAIT_OBJECT_0+1:
    ::ResetEvent(m_hEvent[1]);
    break;
    case WAIT_OBJECT_0+2:
    ::ResetEvent(m_hEvent[2]);
    break;
    }
    return FALSE;
    }
    ::ResetEvent(m_hEvent[0]);
    }
    else
    {
    return FALSE;
    }
    }        if(pPostDataBuf != NULL && dwPostSize !=0 )
    {

    for(n=0; n<=(int)dwPostSize/SENDBUFFERSIZE; n++)
    {
    // ::ResetEvent(m_hEvent[0]);  //写数据
    DWORD dwBytesUnWrite = dwPostSize - dwBytesWrittenTotal;
    if(dwBytesUnWrite != 0)
    {
    if((dwBytesRead=dwBytesUnWrite % SENDBUFFERSIZE) ==0)
    dwBytesRead = SENDBUFFERSIZE;
    }
    else
    break;
    memcpy(pBuffer,pPostDataBuf+dwBytesWrittenTotal,dwBytesRead);
    if(!::InternetWriteFile(m_hRequest,pBuffer,dwBytesRead,&dwBytesWritten))   {
    DWORD nError = GetLastError();
    if (nError == ERROR_IO_PENDING) 

    DWORD dwRet = WaitExitEvent();
    if(dwRet != WAIT_OBJECT_0)
    {
    switch(dwRet)
    {
    case WAIT_OBJECT_0+1:
    ::ResetEvent(m_hEvent[1]);
    break;
    case WAIT_OBJECT_0+2:
    ::ResetEvent(m_hEvent[2]);
    break;
    }
    return FALSE;
    }
    ::ResetEvent(m_hEvent[0]);
    }  
    }
    memset(pBuffer,0,SENDBUFFERSIZE);
    dwBytesWrittenTotal += dwBytesWritten;
    }
    }

    }

    if(!::HttpEndRequest(m_hRequest,NULL,HSR_INITIATE,(DWORD)this))
    {
    DWORD dwError = ::GetLastError();
    if(ERROR_IO_PENDING == dwError)
    {
    // ::ResetEvent(m_hEvent[0]);
    DWORD dwRet = WaitExitEvent();
    if(dwRet != WAIT_OBJECT_0)
    {
    switch(dwRet)
    {
    case WAIT_OBJECT_0+1:
    ::ResetEvent(m_hEvent[1]);
    break;
    case WAIT_OBJECT_0+2:
    ::ResetEvent(m_hEvent[2]);
    break;
    }

    return FALSE;
    }
    ::ResetEvent(m_hEvent[0]);
    }
    else if(ERROR_INTERNET_FORCE_RETRY == dwError)
    {
    goto again;
    }
    else
    {
       
    return FALSE;
    }
    }
      

  5.   

    //获取返回的文件类型HTTP_QUERY_CONTENT_TYPE
         
    char ConTypeBuf[512] = {0};
    DWORD nConTypeBufLen = 512;
    if(::HttpQueryInfo(m_hRequest,HTTP_QUERY_CONTENT_TYPE,ConTypeBuf,&nConTypeBufLen,NULL))
    {
    strConTentType = CString(ConTypeBuf,nConTypeBufLen);
    } //返回头状态码信息
    DWORD m_dwStatusCode;
    DWORD dwStatusSize = sizeof(m_dwStatusCode);
    //CFile file;
    //if(!file.Open(strFileName,CFile::modeCreate|CFile::modeReadWrite))
    // return FALSE;
    if(FALSE == ::HttpQueryInfo(m_hRequest,HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER,&m_dwStatusCode,&dwStatusSize,NULL))
    {
    return FALSE;
    }
    if(HTTP_STATUS_OK != m_dwStatusCode)
    {
    if(m_dwStatusCode > 300 && m_dwStatusCode<400)
    {
    CString strLocationURL = "";
    if(!GetLocationURL(strLocationURL))
    return FALSE;
    else
    {
    nJumCounts++;
    if(nJumCounts>5)
    {
    nJumCounts = 0;
    return FALSE;
    }
    CloseHandle();
    return GetHttpFile(HTTP_REQUEST_GET,strLocationURL,m_szUrl,NULL,0);
    }
    }
    else
      return FALSE;
    }
         //获取返回的编码
    nJumCounts = 0;
    char InBuf[512] = {0};
    DWORD nBufLen = 512;
    if(::HttpQueryInfo(m_hRequest,HTTP_QUERY_CONTENT_ENCODING,InBuf,&nBufLen,NULL))
    {
    CString strEnCoding = CString(InBuf);  
    strEnCoding.MakeLower();
    if(strEnCoding.CompareNoCase("deflate") == 0)
       m_nPageType = 2;
    else if(strEnCoding.CompareNoCase("gzip") == 0)
    m_nPageType = 1;
    else
    m_nPageType = 0;
    }
        else
    m_nPageType = 0;
    //获取返回数据长度并读取数据。
    bAllDone = FALSE;
    m_pOutPage.lpszBuffer = NULL; 
    m_pOutPage.lpszBuffer = (char*)malloc(4*1024*sizeof(char));                //分配页面空间
    DWORD dwMemTotalLen = 4*1024*sizeof(char);
    m_pOutPage.nSize = 0;
    if(NULL == m_pOutPage.lpszBuffer)
    return FALSE;
        memset(m_pOutPage.lpszBuffer,0,dwMemTotalLen); DWORD m_dwContentLength;
    DWORD dwLengthSize = sizeof(m_dwContentLength);
    if(FALSE == ::HttpQueryInfo(m_hRequest,HTTP_QUERY_CONTENT_LENGTH|HTTP_QUERY_FLAG_NUMBER,&m_dwContentLength,&dwLengthSize,NULL))
    {
    char lpReadBuff[4 * 1024+1] = {0}; 
    while(bAllDone == FALSE) 

    INTERNET_BUFFERS InetBuff={0}; 
    InetBuff.dwStructSize = sizeof(INTERNET_BUFFERS); 
    InetBuff.lpvBuffer = lpReadBuff; 
    InetBuff.dwBufferLength = sizeof(lpReadBuff)-1; 

    if (!::InternetReadFileEx(m_hRequest,&InetBuff,IRF_ASYNC,(DWORD)this)) 

    if (GetLastError() == ERROR_IO_PENDING) 

    DWORD dwRet = WaitExitEvent();
    if(dwRet != WAIT_OBJECT_0)
    {
    switch(dwRet)
    {
    case WAIT_OBJECT_0+1:
    ::ResetEvent(m_hEvent[1]);
    break;
    case WAIT_OBJECT_0+2:
    ::ResetEvent(m_hEvent[2]);
    break;
    }
    if(m_pOutPage.lpszBuffer)
    {
    free(m_pOutPage.lpszBuffer);
    m_pOutPage.lpszBuffer = NULL;
    m_pOutPage.nSize = 0;
    }
    return FALSE;
    }
    ::ResetEvent(m_hEvent[0]);
    }  

    else
    {
    /*if(WAIT_OBJECT_0 == ::WaitForSingleObject(m_hEvent[2],0))
    {
    if(m_pOutPage.lpszBuffer)
    {
    free(m_pOutPage.lpszBuffer);
    m_pOutPage.lpszBuffer = NULL;
    m_pOutPage.nSize = 0;
    }
    return FALSE;
    }*/
    std::cout<<"true"<<std::endl;
    }
    lpReadBuff[InetBuff.dwBufferLength] = 0;             if(m_pOutPage.nSize + InetBuff.dwBufferLength > dwMemTotalLen)          //空间不够重新分配页面空间
    {
    char *tempBuf = m_pOutPage.lpszBuffer;
    dwMemTotalLen = m_pOutPage.nSize + InetBuff.dwBufferLength;
    m_pOutPage.lpszBuffer = (char*)realloc(m_pOutPage.lpszBuffer,dwMemTotalLen);

    if(NULL == m_pOutPage.lpszBuffer)
    {
    free(tempBuf);
    return FALSE;
    }
    }
    memcpy(m_pOutPage.lpszBuffer+m_pOutPage.nSize,InetBuff.lpvBuffer,InetBuff.dwBufferLength);
    m_pOutPage.nSize += InetBuff.dwBufferLength;
                
    // file.Write(InetBuff.lpvBuffer,InetBuff.dwBufferLength);
    if (InetBuff.dwBufferLength == 0) 

    bAllDone = TRUE;
    break; 

    Sleep(100);
    }  //END WHILE }
    else
    {

    char lpReadBuff[4 * 1024+1] = {0}; 
    for(DWORD i=0;i<m_dwContentLength;)
    {
    INTERNET_BUFFERS i_buf = {0};
    i_buf.dwStructSize = sizeof(INTERNET_BUFFERS);
    i_buf.lpvBuffer = lpReadBuff;
    i_buf.dwBufferLength = sizeof(lpReadBuff)-1;

    if(FALSE == ::InternetReadFileEx(m_hRequest,&i_buf,IRF_ASYNC,(DWORD)this))
    {
    if(ERROR_IO_PENDING == ::GetLastError())
    {
    DWORD dwRet = WaitExitEvent();
    if(dwRet != WAIT_OBJECT_0)
    {
    switch(dwRet)
    {
    case WAIT_OBJECT_0+1:
    ::ResetEvent(m_hEvent[1]);
    break;
    case WAIT_OBJECT_0+2:
    ::ResetEvent(m_hEvent[2]);
    break;
    }
    if(m_pOutPage.lpszBuffer)
    {
    free(m_pOutPage.lpszBuffer);
    m_pOutPage.lpszBuffer = NULL;
    m_pOutPage.nSize = 0;
    }
    return FALSE;
    }
    ::ResetEvent(m_hEvent[0]);
    }
    else
    {
    // delete[] i_buf.lpvBuffer;
    return FALSE;
    }
    }
    else
    {
    /* if(WAIT_OBJECT_0 == ::WaitForSingleObject(m_hEvent[2],0))
    {
    ::ResetEvent(m_hEvent[2]);
    // delete[] i_buf.lpvBuffer;
    if(m_pOutPage.lpszBuffer)
    {
    free(m_pOutPage.lpszBuffer);
    m_pOutPage.lpszBuffer = NULL;
    m_pOutPage.nSize = 0;
    }
    return FALSE;
    }*/
    std::cout<<"true"<<std::endl;
    }  
    i += i_buf.dwBufferLength;
    if(m_pOutPage.nSize + i_buf.dwBufferLength > dwMemTotalLen)          //空间不够重新分配页面空间
    {
    char *tempBuf = m_pOutPage.lpszBuffer;
    dwMemTotalLen = m_pOutPage.nSize + i_buf.dwBufferLength;
    m_pOutPage.lpszBuffer = (char*)realloc(m_pOutPage.lpszBuffer,dwMemTotalLen);

    if(NULL == m_pOutPage.lpszBuffer)
    {
    free(tempBuf);
    return FALSE;
    }
    }
    memcpy(m_pOutPage.lpszBuffer+m_pOutPage.nSize,i_buf.lpvBuffer,i_buf.dwBufferLength);
    m_pOutPage.nSize += i_buf.dwBufferLength;
    if(bAllDone)
    break;
    Sleep(100);
    }
    }
    return TRUE;

    }
    当回调函数在INTERNET_STATUS_RECEIVING_RESPONSE 和 INTERNET_STATUS_RESPONSE_RECEIVED这两种状态一直切换时,好像InternetReadFileEx不会立即返回,调试的时候一直卡在里面。
      

  6.   

    case INTERNET_STATUS_HANDLE_CREATED:
    OnInternetHandleCreated(dwContext,(LPINTERNET_ASYNC_RESULT)lpvStatusInformation);
    感觉问题在这一句,它应该会不断触发新的回调函数调用的吧,造成死循环了。
      

  7.   

    OnInternetHandleCreated这个是我写的一个函数,来判断创建的句柄是什么类型的。
    void CAsynHttpClient::OnInternetHandleCreated(DWORD dwContext, LPINTERNET_ASYNC_RESULT lpInetStatusResult)
    {
        if(NULL == lpInetStatusResult)
        {
            //ATLASSERT( 0 );
            return;
        }
    CAsynHttpClient *pObj = (CAsynHttpClient*)dwContext;
        //pObj->m_hFile = HINTERNET(lpInetStatusResult->dwResult);
        HINTERNET    hInet = HINTERNET(lpInetStatusResult->dwResult);
        DWORD        dwInetHandleType;
        DWORD        dwTypeLen = sizeof(dwInetHandleType);

        ::InternetQueryOption(hInet, INTERNET_OPTION_HANDLE_TYPE, &dwInetHandleType, &dwTypeLen);
        switch(dwInetHandleType) 
        {
        case INTERNET_HANDLE_TYPE_CONNECT_HTTP:
           //   连接句柄
    if(pObj->m_hInternetConn == NULL)
    pObj->m_hInternetConn = hInet;     // 
            break;
        case INTERNET_HANDLE_TYPE_HTTP_REQUEST:
            //CloseInternetFile();    //    请求资源句柄
    if(pObj->m_hRequest == NULL)
    pObj->m_hRequest = hInet;    //
            break; 
        default:
            break;
        }
    }
      

  8.   

    回调函数是一直在 INTERNET_STATUS_RECEIVING_RESPONSE 和 INTERNET_STATUS_RESPONSE_RECEIVED这两种状态切换。接收到的数据一直是0