InternetSetStatusCallback设置的回调函数中dwInternetStatus一直在回传 ,并在两种状态
INTERNET_STATUS_RECEIVING_RESPONSE 和 INTERNET_STATUS_RESPONSE_RECEIVED中切换 。 状态为INTERNET_STATUS_RESPONSE_RECEIVED时lpvStatusInformation的值一直为0。
INTERNET_STATUS_RECEIVING_RESPONSE 和 INTERNET_STATUS_RESPONSE_RECEIVED中切换 。 状态为INTERNET_STATUS_RESPONSE_RECEIVED时lpvStatusInformation的值一直为0。
解决方案 »
- SendMessage没有效果,PostMessage去有效果,我哪里用错了?
- 问题多多,一个接一个,关于Tooltip提示
- h.264中提取运动矢量的问题(int16_t和int有何差别)
- 关于剪切板的使用问题。紧急求救
- 十万火急,多文档新建一个ChildFrame 显示 FormView,如何让它的标题出现在Window菜单下
- VC + ADO 压缩各类数据库(MySql、DB2、SQL、ACCESS)有没有统一的方法?
- 创建无模式对话框的疑问??
- 100分请教一个问题,
- 紧急求助!十万火急!
- 关于CDialogBar的问题
- 如何在Pocket PC2003模拟器中注册ActiveX控件
- activex控件cab更新 会提示重启电脑
查看一下 hInternet是否有什么问题,多分析一些错误原因
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; }
}
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;
}
}
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不会立即返回,调试的时候一直卡在里面。
OnInternetHandleCreated(dwContext,(LPINTERNET_ASYNC_RESULT)lpvStatusInformation);
感觉问题在这一句,它应该会不断触发新的回调函数调用的吧,造成死循环了。
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;
}
}