⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 httpdown.cpp

📁 本程序是VC为平台开发的股票资讯系统
💻 CPP
字号:
// HttpDown.cpp : implementation file
//

#include "stdafx.h"
#include "HttpDown.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CHttpDown

static const TCHAR szHeaders[] = _T("Accept: */*\r\n");
static const TCHAR AgentName[] = _T("USER");
static DWORD dwHttpRequestFlags =	INTERNET_FLAG_EXISTING_CONNECT |  INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE ; 

void CSearchSession::OnStatusCallback(DWORD dwContext, 
		DWORD dwInternetStatus,LPVOID lpvStatusInfomration, 
		DWORD dwStatusInformationLen)
{
	CString strStatus;
	switch(dwInternetStatus)
	{
	case INTERNET_STATUS_STATE_CHANGE:	
		strStatus= _T("服务器正忙");
		break;
	case INTERNET_STATUS_REQUEST_COMPLETE:
		strStatus= _T("请求完成");
		break;
	case INTERNET_STATUS_CONNECTING_TO_SERVER:
		strStatus= _T("正在连接到服务器...");
		break;
	case INTERNET_STATUS_RESOLVING_NAME:
		strStatus.Format(_T("解析主机地址..."));
		break;
	case INTERNET_STATUS_NAME_RESOLVED:	
		strStatus.Format(_T("主机地址已确认"));
		break;
	case INTERNET_STATUS_CONNECTED_TO_SERVER:
		strStatus= _T("成功连接到服务器");
		break;
	case INTERNET_STATUS_SENDING_REQUEST:	
		strStatus= _T("正在发送请求...");
		break;
	case INTERNET_STATUS_REQUEST_SENT:	
		strStatus= _T("请求发送成功");
		break;
	case INTERNET_STATUS_RECEIVING_RESPONSE:
		strStatus= _T("正在接收数据...");
		break;
//		strStatus= _T("正在接收回应...");
//		break;
//	case INTERNET_STATUS_RESPONSE_RECEIVED:	
//		strStatus= _T("回应接收成功");
//		break;
	case INTERNET_STATUS_CLOSING_CONNECTION:
		strStatus= _T("正在关闭连接...");
		break;
	case INTERNET_STATUS_CONNECTION_CLOSED:	
		strStatus= _T("连接关闭成功");
		break;
	case INTERNET_STATUS_HANDLE_CLOSING:
		strStatus= _T("正在关闭连接...");
	case INTERNET_STATUS_HANDLE_CREATED:
		strStatus= _T("连接已经建立");
		break;
	case INTERNET_STATUS_REDIRECT:
		strStatus = _T("重定向地址");
		break;
//	case INTERNET_STATUS_CTL_RESPONSE_RECEIVED:
//	default:
//		strStatus.Format(_T("未知状态: %d"), dwInternetStatus);
//		break;
	}

	LPCTSTR pStauts = strStatus;
	::SendMessage (AfxGetMainWnd()->m_hWnd,
		WM_USER_SERVER_STATUS, (WPARAM)dwContext,(LPARAM)pStauts);
}

CHttpDown::CHttpDown()
{
	m_pSession = NULL;
	m_pServer =NULL;
	m_pFile= NULL;
}

CHttpDown::~CHttpDown()
{
	CleanUp();
}

/////////////////////////////////////////////////////////////////////////////
// CHttpDown message handlers

BOOL CHttpDown::InitServer(URLParams *pURLParams)
{
	
	try{
		if(!pURLParams->m_strProxy.IsEmpty())
			m_pSession = new CSearchSession(AgentName,pURLParams->m_dwContext,
				INTERNET_OPEN_TYPE_PROXY,pURLParams->m_strProxy,pURLParams->m_strPort);   
		else
			m_pSession = new CSearchSession(AgentName,pURLParams->m_dwContext);
		int ntimeOut = 30;  // very important, can cause a Server time-out if set to low
							// or hang the thread if set to high.
		/*
		The time-out value in milliseconds to use for Internet connection requests. 
		If a connection request takes longer than this timeout, the request is canceled.
		The default timeout is infinite. */
		m_pSession->SetOption(INTERNET_OPTION_CONNECT_TIMEOUT,1000* ntimeOut);
		
		/* The delay value in milliseconds to wait between connection retries.*/
		m_pSession->SetOption(INTERNET_OPTION_CONNECT_BACKOFF,1000);
		
		if(pURLParams->m_dwTimeOut != 0)
			m_pSession->SetOption(INTERNET_OPTION_RECEIVE_TIMEOUT,
				&pURLParams->m_dwTimeOut,sizeof(pURLParams->m_dwTimeOut));

		/* The retry count to use for Internet connection requests. If a connection 
		attempt still fails after the specified number of tries, the request is canceled.
		The default is five. */
		m_pSession->SetOption(INTERNET_OPTION_CONNECT_RETRIES,1);
        m_pSession->EnableStatusCallback(TRUE);

		}
		catch (CInternetException* pEx)
		{
			// catch errors from WinINet
			//pEx->ReportError();
			m_pSession = NULL;
			pEx->Delete();

			return FALSE ;
		}

	return TRUE;
}

BOOL CHttpDown::ParseURL(URLParams *pURLParams)
{
	BOOL bRet = FALSE;
	if(pURLParams->m_pszURL.IsEmpty()) return bRet;

	LPCTSTR lpsz = pURLParams->m_pszURL;
	if(lpsz  == NULL) return bRet;

	int nLen = lstrlen(lpsz);
	int i=0;
	while (nLen)
	{
		if( *lpsz == '/')	i++;
		++lpsz;
		nLen--;
		
	}
	if( i< 3) pURLParams->m_pszURL += '/';

	try
	{
		AfxParseURL(pURLParams->m_pszURL,pURLParams->m_dwServiceType,
			pURLParams->m_strServerName,pURLParams->m_strObject,
			pURLParams->m_nPort);
	}
	catch (CInternetException* pEx)
	{
		// catch errors from WinINet
		//pEx->ReportError();
		pEx->Delete();
		return bRet;
	}

	
	lpsz = pURLParams->m_strObject;
	if(lpsz  == NULL) return bRet;
	bRet = TRUE;
	nLen = lstrlen(lpsz);

	BOOL bdot = FALSE;
	while (nLen)
	{
		if( *lpsz == '.') bdot = TRUE;
		++lpsz;
		nLen--;
		
	}
	if(pURLParams->m_strObject.GetLength()-1 > 0)
	{
	if( bdot == FALSE && pURLParams->m_strObject[pURLParams->m_strObject.GetLength()-1] != '/')
		pURLParams->m_strObject += '/';
	}

	return bRet;
}

BOOL CHttpDown::GetHttpFile(LPCTSTR ServerName,LPCTSTR strObject,URLParams *pURLParams)
{
	CString rString;
	LPCTSTR lpsz;
	LPCTSTR lpszStop;
	int j=0;
	TCHAR sz[4096];
	memset(sz,'\0',sizeof(sz));

	if(strObject == NULL) return FALSE;

	DWORD dwRet = GetHttpStatus(ServerName, strObject,pURLParams);
	if(dwRet != HTTP_STATUS_OK){
		CString strStatus;
		switch(dwRet)
		{
		case ERROR_INTERNET_TIMEOUT:
			strStatus.Format(_T("与服务器连接超时"));
			break;
		case ERROR_INTERNET_NAME_NOT_RESOLVED:
			strStatus.Format(_T("无法连接到指定页面"));
			break;
		case HTTP_STATUS_NOT_FOUND:
			strStatus.Format(_T("找不到服务器"));
			break;
//		default:
//			strStatus.Format(_T("未知错误: %d"),dwRet);
//			break;
		}
		LPCSTR line = strStatus;
		::SendMessage(AfxGetMainWnd()->m_hWnd,
			WM_USER_SERVER_STATUS,0,(LPARAM)line);
//		::SendMessage(AfxGetMainWnd()->m_hWnd,
//			WM_USER_SEND_ERRINFO,0,(LPARAM)line);

		return FALSE;
	}

	long xx = pURLParams->m_dwIngoreLength;
	CString strLength;
	m_pFile->QueryInfo(HTTP_QUERY_CONTENT_LENGTH,strLength);
	DWORD dwLength = atol(strLength);
	if(pURLParams->m_dwIngoreLength != -1 && 
		dwLength > pURLParams->m_dwIngoreLength) return FALSE;

	if(m_pFile != NULL && m_pServer != NULL && m_pSession != NULL)
	{
		try
		{
			while (m_pFile->ReadString(sz, 4095))
			{
					rString = _T("");		
					lpsz = sz;
					if(lpsz != NULL)
					{
						lpszStop = sz + lstrlen(sz);
						j=0;
						while (lpsz < lpszStop)
						{
//							if(*lpsz =='\n')	rString += "\r\n";
							if(*lpsz =='\n')	rString += '\n';

							else rString += sz[j];

							++lpsz;
							j++;

						}
						pURLParams->m_Contents += rString;
					}
			}
		}
		catch (CInternetException* pEx)
		{
			m_pFile= NULL;
			pEx->Delete();
			return 0;
		}
	}

	return TRUE;
}

DWORD CHttpDown::NewConnection(LPCTSTR ServerName,LPCTSTR strObject,URLParams *pURLParams)
{
	if(ServerName  == NULL || strObject == NULL) return 0;
	DWORD dwRet =  HTTP_STATUS_OK;
	INTERNET_PORT nPort = INTERNET_DEFAULT_HTTP_PORT;

	try{
		if(!pURLParams->m_strProxy.IsEmpty())
			m_pSession = new CSearchSession(AgentName,pURLParams->m_dwContext,
				INTERNET_OPEN_TYPE_PROXY,pURLParams->m_strProxy,pURLParams->m_strPort);   
		else
			m_pSession = new CSearchSession(AgentName,pURLParams->m_dwContext);
		int ntimeOut = 30;
		/*
		The time-out value in milliseconds to use for Internet connection requests. 
		If a connection request takes longer than this timeout, the request is canceled.
		The default timeout is infinite. */
		m_pSession->SetOption(INTERNET_OPTION_CONNECT_TIMEOUT,1000* ntimeOut);
		
		/* The delay value in milliseconds to wait between connection retries.*/
		m_pSession->SetOption(INTERNET_OPTION_CONNECT_BACKOFF,1000);

		if(pURLParams->m_dwTimeOut != 0)
			m_pSession->SetOption(INTERNET_OPTION_RECEIVE_TIMEOUT,
				&pURLParams->m_dwTimeOut,sizeof(pURLParams->m_dwTimeOut));

		/* The retry count to use for Internet connection requests. If a connection 
		attempt still fails after the specified number of tries, the request is canceled.
		The default is five. */
		m_pSession->SetOption(INTERNET_OPTION_CONNECT_RETRIES,2);

		m_pSession->EnableStatusCallback(TRUE);
//		m_pSession->m_strHttpSite.Format(_T("%s%s"),ServerName,strObject);
	}
	catch (CInternetException* pEx)
	{
		// catch errors from WinINet
		dwRet = pEx->m_dwError;
		m_pSession=NULL;
		pEx->Delete();
		return  dwRet;
	}
	try
	{
		m_pServer = m_pSession->GetHttpConnection(ServerName,nPort);
	}
	catch (CInternetException* pEx)
	{
		// catch errors from WinINet
		dwRet = pEx->m_dwError;
		m_pServer = NULL;
		pEx->Delete();
		CleanUp();
		return   dwRet;
	}

	m_strCurrentServer = ServerName;
	try
	{
		// This can never return NULL. The call may have failed, but it can
		// never be null.
		m_pFile = m_pServer->OpenRequest(_T("GET"),strObject,NULL, 
			pURLParams->m_dwContext, NULL, NULL, dwHttpRequestFlags);
		m_pFile->SendRequest();
	}
	catch (CInternetException* pEx)
	{
		// catch errors from WinINet
		dwRet = pEx->m_dwError;
		m_pFile = NULL;
		pEx->Delete();
		CleanUp();
		return dwRet;
	}

	return dwRet;
}

DWORD CHttpDown::GetHttpStatus(LPCTSTR lpServerName,LPCTSTR strObject,URLParams *pURLParams)
{
	if(lpServerName  == NULL || strObject == NULL) return 0;

	INTERNET_PORT nPort = INTERNET_DEFAULT_HTTP_PORT;
	DWORD dwRet =  1;

	if (m_pSession == NULL)
		return dwRet;
//	m_pSession->m_strHttpSite.Format(_T("%s%s"),lpServerName,strObject);

	dwRet =  2;
	if(m_pFile != NULL)
	{
		m_pFile->Close();
		delete m_pFile;
		m_pFile=NULL;
	}
	
	if (m_strCurrentServer != lpServerName)
	{
		// Picked a new server, close out connection and make a new one:
		if (m_pServer != NULL)
		{
			m_pServer->Close ();
			delete m_pServer;
			m_pServer = NULL;
		}
	}

	if (m_pServer == NULL)
	{
		try
		{
			m_pServer = m_pSession->GetHttpConnection(lpServerName,nPort);
		}
		catch (CInternetException* pEx)
		{
			dwRet = pEx->m_dwError;
			m_pServer = NULL;
			pEx->Delete();
			if(!CleanUp()) return FALSE;
			return dwRet;
		}

		m_strCurrentServer = lpServerName;
	}


	if (m_pServer == NULL) return dwRet;
  
	try
	{
		// This can never return NULL. The call may have failed, but it can
		// never be null.
		m_pFile = m_pServer->OpenRequest(CHttpConnection::HTTP_VERB_GET,
			strObject,NULL, pURLParams->m_dwContext, NULL, NULL, dwHttpRequestFlags);
		m_pFile->SendRequest();
	}
	catch (CInternetException* pEx)
	{
		// catch errors from WinINet
		//pEx->ReportError();
		dwRet = pEx->m_dwError;
		m_pFile = NULL;
		pEx->Delete();
		if(!CleanUp()) return FALSE;
		if(dwRet == ERROR_INTERNET_TIMEOUT ) Sleep(1000);  // Connection timed out, try again on new connection
		dwRet = NewConnection(lpServerName,strObject,pURLParams);
		if(dwRet != HTTP_STATUS_OK) return dwRet;
	}

	if(m_pFile != NULL)
		m_pFile->QueryInfoStatusCode(dwRet);

	return dwRet;
}

BOOL CHttpDown::CleanUp()
{
	m_strCurrentServer.Empty();
	try
	{
		if(m_pFile != NULL)
		{	m_pFile->Close();
			delete m_pFile;
			m_pFile= NULL;
		}
		if (m_pServer!= NULL)
		{
			m_pServer->Close();
			delete m_pServer;
			m_pServer = NULL;
		}
		if (m_pSession != NULL)
		{
			m_pSession->Close();
			delete m_pSession;
			m_pSession = NULL;
		}
	}
//	catch (CInternetException* pEx)
//	{
//		// catch errors from WinINet
//		pEx->Delete();
//		return FALSE;
//	}
	catch(...)
	{
		return FALSE;
	}

	return TRUE;
}

CString CHttpDown::GetHttpFileGet(LPCTSTR pstrURL,
		DWORD dwContext/* = 1000*/,DWORD dwTimeOut/* = 0*/,
		LPCTSTR pstrProxy/* = NULL*/,LPCTSTR pstrPort/* = NULL*/,
		DWORD dwIngoreLength/* = -1*/)
{
    URLParams *pURLParams = new URLParams;
	pURLParams->m_pszURL = pstrURL;
	pURLParams->m_dwContext = dwContext;
	pURLParams->m_dwTimeOut = dwTimeOut;
	pURLParams->m_dwIngoreLength = dwIngoreLength;
	if(pstrProxy != NULL)
		pURLParams->m_strProxy = pstrProxy;
	if(pstrPort != NULL)
		pURLParams->m_strPort = pstrPort;
	if(!InitServer(pURLParams)) {
		dwError = ERROR_INIT_SERVER;
		delete pURLParams;
//		return NULL;
		return _T("");
	}

	if(pURLParams->m_pszURL.IsEmpty()){
		dwError = ERROR_URL_NULL;
		delete pURLParams;
//		return NULL;
		return _T("");
	}

	if(!pURLParams){
		dwError = ERROR_NEW_PARAMS;
		delete pURLParams;
//		return NULL;
		return _T("");
	}

	if(!ParseURL(pURLParams)) {
		dwError = ERROR_PARSE_URL;
		delete pURLParams;
//		return NULL;
		return _T("");
	}

	if(!GetHttpFile(pURLParams->m_strServerName,pURLParams->m_strObject,pURLParams))
	{
		dwError = ERROR_GET_HTTPFILE;
		delete pURLParams;
//		return NULL;
		return _T("");
	}

//	LPCTSTR pContent = pURLParams->m_Contents;
//	delete pURLParams;
//	return pContent;
	return pURLParams->m_Contents;
}

CString CHttpDown::GetLastErrorText()
//LPCTSTR CHttpDown::GetLastErrorText()
{
	CString strError;
	switch(dwError)
	{
	case ERROR_NEW_PARAMS:
		strError.Format(_T("内存申请失败"));
		break;
	case ERROR_INIT_SERVER:
		strError.Format(_T("连接到服务器失败"));
		break;
	case ERROR_URL_NULL:
		strError.Format(_T("地址为空"));
		break;
	case ERROR_PARSE_URL:
		strError.Format(_T("解析地址失败"));
		break;
	case ERROR_GET_HTTPFILE:
		strError.Format(_T("接收文件时出错"));
		break;
	}
//	LPCTSTR pstrError = strError;
//	return pstrError;
	return strError;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -