利用Internet协议实现各种文件的下载

  
头文件:///
#ifndef  _HTTP_H
#define _HTTP_H
#include<windows.h>
#include<Wininet.h>
#include<string>
#include<tchar.h>
using namespace std;
#define MAX_ZIP  3
#define ZIP_PATH_URL 256
class HttpFile
{
public:
	HttpFile();
	bool User_interface();
	~HttpFile();
private:
	bool HttpConnection(LPCTSTR lpszUrl, 
	 								 LPCTSTR lpszHeaders, 
									 const void* pPostData, 
									 int nLen,
									 std::string &strResult,
									 char *zipname);
	bool SendAnalyseResult(LPCTSTR lpszUrl,  LPCTSTR lpszHeaders,const void* pPostData, int nLen,  std::string &strResult);	
	bool RecvFileUrl();
	bool RecvFileZip();
public:
	HINTERNET hOpen ;
	HINTERNET hConnect ;
	HINTERNET hRequest ;
	LPCTSTR lpszHeaders;
	LPCTSTR zipDirUrl;
	LPCTSTR zipDownloadzUrl;
	LPCTSTR zipUploadUrl;
	DWORD dwFlags;	
	BOOL bRet;
	string strResult;
	const void* pPostData;	

	unsigned short reportid_label;
	unsigned short count_label;
	unsigned short file1_label;
	unsigned short file2_label;
	unsigned short file3_label;
	unsigned short tmp_reportid[11];
	unsigned short tmp_count[11];
	unsigned short tmp_file1[11];
	unsigned short tmp_file2[11];
	unsigned short tmp_file3[11];
	char *p_vid;
	char *p_reportid;
	char *p_count;
	char *p_file1;
	char *p_file2;
	char *p_file3;					
	string  str_reportid;
	string  str_count ;
	wstring  str_file1;
	wstring  str_file2;
	wstring  str_file3;

	struct UrlInformation
	{
		unsigned short vid;
		unsigned short type;
		unsigned short day;
		unsigned long reportid;
		unsigned short count;
		LPCTSTR productkey;
		LPCTSTR version;
		TCHAR *zipurl[MAX_ZIP];
	}s_Url;
	UrlInformation u_url[10];	 	
};
#endif
.cpp文件//
#include "stdafx.h"
#include"httpfile.h"
#include<assert.h>
#include<stdlib.h>
#include<tchar.h>
#include<string>
#include<iostream>
using namespace std;
#include "ETCompressInterface.h"
#include "ETZipCompress.h"

void DemoCompressProgressCallback(LPCTSTR pTargetZipFile,
								  LPCTSTR pCurrentFile,
								  UINT64 u64FileCount,
								  UINT64 u64FileIndex,
								  UINT64 u64AllFileTotalSize,
								  UINT64 u64AllFileDeflatedSize,
								  UINT64 u64FileTotalSize,
								  UINT64 u64FileDeflatedSize,
								  BOOL   isLastTime
										) 
{
	//8字节的UINT64,是无法直接格式化的,直接格式化只支持四个字节的整数
	_tprintf(_T("CF->%s,Index->%d,ToSize->%d\n"),pCurrentFile,(int)u64FileIndex,(int)u64AllFileDeflatedSize);
}
void DemoDecompressProgressCallback(LPCTSTR pTargetZipFile,
									LPCTSTR pCurrentFile,
									UINT64 u64FileCount,
									UINT64 u64FileIndex,
									UINT64 u64FileTotalSize,
									UINT64 u64FileDeflatedSize,
									BOOL   isLastTime
									) 
{
	_tprintf(_T("CF->%s,Index->%d,FileSize->%d,DefSize->%d\n"),pCurrentFile,(int)u64FileIndex,(int)u64FileTotalSize,(int)u64FileDeflatedSize);
}
/************************************************************************/
/* User_interface是留给用户的唯一接口*/
/************************************************************************/
bool HttpFile::User_interface()
{		
	bool flag_recieive = false;	
	bool flag_test = false;
	flag_recieive = RecvFileUrl();		
	if (flag_recieive)
	{
		flag_test = RecvFileZip();
		cout<<"download success!"<<endl;
	}
	else 
	{
		cout<<"please check the RecvFileUrl function !"<<endl;
	}
	CETCompressInterface* pCompress = new CETZipCompress();	
	for (int i = 0; i<10; i++)
	{
		for (int j =0; j<3; j++)
		{
			char *path="G:/我的资料库/Documents/Visual Studio 2008/Projects/cosmos_307test/";
			char *szPath= new char[strlen(path)+15];
			char *uncompresspath = new char[40]; 

			sprintf(szPath,"%scosmos%d.zip",path,i*10+j);
			sprintf(uncompresspath,"D:/cosmos/cosmos%d",i*10+j);			
			pCompress->SetTargetFile(szPath);
			pCompress->SetTargetPath(uncompresspath);
			bool result = false;
			result = pCompress->Decompress();
			if (!result)
			{
				cout<<"解压失败!"<<endl;
			}
			else
				cout<<"解压成功!"<<endl;	
			delete []szPath;
			delete[]uncompresspath;
		}
	}
	return true;
}

/*===========================构造函数===============================*/
HttpFile::HttpFile()
{
	//WSADATA wsaData = {0};
	//WSAStartup(MAKEWORD(2, 2), &wsaData);
	hOpen = NULL;
	hConnect = NULL;
	hRequest = NULL;
	dwFlags = INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE;
	bRet = FALSE;
	strResult = "";
	pPostData = NULL;
	lpszHeaders = NULL;		
	for(int i = 0; i<10; i++)
	{
		u_url[i].count = 0;
		u_url[i].day = 0;
		u_url[i].productkey = _T("");
		u_url[i].reportid = 0;
		u_url[i].type = 0;
		u_url[i].version = _T("");
		u_url[i].vid = 0;
		for(int j = 0; j<3; j++)
		{
			u_url[i].zipurl[j] = new wchar_t[ZIP_PATH_URL];
		}
	}
	reportid_label = 0;
	count_label = 0;
	file1_label = 0;
	file2_label = 0;
	file3_label = 0;
	for(int i = 0; i<11; i++)
	{
		tmp_reportid[i] = 0;
		tmp_count[i] = 0;
		tmp_file1[i] = 0;
		tmp_file2[i] = 0;
		tmp_file3[i] = 0;
	}
	p_vid = NULL;
	p_reportid =NULL;
	p_count =NULL;
	p_file1 =NULL;
	p_file2 =NULL;
	p_file3 =NULL;					
	str_reportid = "";
	str_count = "";
	str_file1 = L"";
	str_file2 = L"";
	str_file3 = L"";
}
/*===========================构造函数到此结束===============================*/

/*===========================upload function start==================================*/
bool  HttpFile::SendAnalyseResult(LPCTSTR lpszUrl,  LPCTSTR lpszHeaders,
								  const void* pPostData,  int nLen,
								  std::string &strResult)
{
	cout<<"waitting"<<endl;
	return true;
}
/*===========================upload function end===============================*/

/*===========================download function start==================================*/
bool HttpFile::RecvFileUrl()
{
	char *urlDir = "G:/我的资料库/Documents/Visual Studio 2008/Projects/cosmos_307test/cosmos3.txt";
	zipDirUrl =_T("http://crashreport.yy.duowan.com/crashreport/get_version_top.php?productkey=YY&version=4.10.0.0&type=1&day=0");
	HttpConnection(zipDirUrl,NULL,NULL,0,strResult,urlDir);

	int tmp_vid = 0;
	string tmpstr = "";									
	tmp_vid = strResult.find('=',0);
	tmp_vid++;
	while (strResult[tmp_vid] != '\r')
	{
		tmpstr+= strResult[tmp_vid];
		tmp_vid++;
	}
	tmp_vid +=2;
	p_vid = new char[tmpstr.length()+1];
	strcpy(p_vid,tmpstr.c_str());	

	for (int j = 0;j<10; j++ )         
	{
		u_url[j].vid = atoi(p_vid);						
	}
	delete []p_vid;
	p_vid =NULL;

	for (int m = 1; m<11; m++)
	{
		tmp_reportid[m] = strResult.find("reportid",tmp_reportid[m-1]+8);//将top10的reportid每一分组的下表记录下来							
		tmp_count[m] = strResult.find("count",tmp_reportid[m]+5);//将top10的count每一分组的下表记录下来					   
		tmp_file1[m] = strResult.find("file",tmp_count[m]);//将top10的file1每一分组的下表记录下来						
		tmp_file2[m] = strResult.find("file",tmp_file1[m]+4);//将top10的file2每一分组的下表记录下来					
		tmp_file3[m] = strResult.find("file",tmp_file2[m]+4);//将top10的file3每一分组的下表记录下来						
	}
	for (int i = 0; i<10; i++)
	{
		reportid_label = strResult.find('=',tmp_reportid[i+1]);
		count_label = strResult.find('=',tmp_count[i+1]);
		file1_label =  strResult.find('=',tmp_file1[i+1]);
		file2_label = strResult.find('=',tmp_file2[i+1]);
		file3_label = strResult.find('=',tmp_file3[i+1]);
		reportid_label++;
		count_label++;
		file1_label++;
		file2_label++;
		file3_label++;
		while (strResult[reportid_label] != '&')
		{
			str_reportid += strResult[reportid_label];
			reportid_label++;
		}
		p_reportid = new char[str_reportid.length()+1];
		strcpy(p_reportid,str_reportid.c_str());	
		u_url[i].reportid = strtoul(p_reportid,0,10);
		delete []p_reportid;
		p_reportid = NULL;

		while (strResult[count_label] != '&')
		{
			str_count += strResult[count_label] ;
			count_label++;
		}
		p_count = new char[str_count.length()+1];
		strcpy(p_count,str_count.c_str());
		u_url[i].count = strtoul(p_count, 0, 10);
		delete []p_count;
		p_count = NULL;

		while (strResult[file1_label] != '&')
		{
			str_file1 += strResult[file1_label];
			file1_label++;
		}
		while (strResult[file2_label] != '&')
		{
			str_file2 += strResult[file2_label];
			file2_label++;
		}
		while (strResult[file3_label] != '\r')
		{
			str_file3 += strResult[file3_label];
			file3_label++;
		}						
		wcscpy(u_url[i].zipurl[0],str_file1.c_str());
		wcscpy(u_url[i].zipurl[1],str_file2.c_str());
		wcscpy(u_url[i].zipurl[2],str_file3.c_str());

		str_reportid = "";
		str_count = "";
		str_file1 = L"";
		str_file2 = L"";
		str_file3 = L"";		
	}       

	return true;
}
bool HttpFile::RecvFileZip()
{
	for (int i = 0; i<10; i++)
	{
		for (int j =0; j<3; j++)
		{
			wstring url = L"http://crashreport.yy.duowan.com";
			url += u_url[i].zipurl[j];
			wcscpy(u_url[i].zipurl[j],url.c_str());   
			FILE *fp;
			char *path="G:/我的资料库/Documents/Visual Studio 2008/Projects/cosmos_307test/";
			char *szPath= new char[strlen(path)+15];
			sprintf(szPath,"%scosmos%d.zip",path,i*10+j);
			//fp=fopen(szPath, "wb+");	
			strResult = "";
			//const std::string U16toUTF8((wchar_t *)u_url[i].zipurl[j]);
			HttpConnection(u_url[i].zipurl[j],NULL,NULL,0,strResult,szPath);
			delete []szPath;			
		}	
	}	
	return true;
}

/*===========================download function end ===============================*/
bool HttpFile::HttpConnection(LPCTSTR lpszUrl, 
							  LPCTSTR lpszHeaders, 
							  const void* pPostData, 
							  int nLen,
							  std::string &strResult,char *zipname)
{	
	TCHAR szHostname[256] = {0};
	URL_COMPONENTS urlcomp = {0};
	char buf[8192] = {0};
	urlcomp.dwStructSize = sizeof(URL_COMPONENTS);
	urlcomp.lpszHostName = szHostname;
	urlcomp.dwHostNameLength = sizeof(szHostname)/sizeof(TCHAR) - 1;
	urlcomp.dwUrlPathLength = 1;
	LPCTSTR acceptTypes[2] = {_T("*/*"), 0};

	do
	{
		if (!InternetCrackUrl(lpszUrl, lstrlen(lpszUrl), 0, &urlcomp))
			break;
		hOpen = InternetOpen(_T(""), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
		if (!hOpen)
			break;
		hConnect = InternetConnect(hOpen, szHostname, urlcomp.nPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
		if (!hConnect)
			break;
		if (pPostData)
			hRequest = HttpOpenRequest(hConnect, _T("POST"), urlcomp.lpszUrlPath, _T("HTTP/1.1"), NULL, acceptTypes, dwFlags, 0);
		else			
			hRequest = HttpOpenRequest(hConnect, _T("GET"), urlcomp.lpszUrlPath, _T("HTTP/1.0"), NULL, acceptTypes, dwFlags, 0);
		if (!hRequest)
			break;
		if (pPostData)
		{
			INTERNET_BUFFERS inbuffer = {0};
			inbuffer.dwStructSize		= sizeof(INTERNET_BUFFERS);
			inbuffer.Next				= NULL;
			inbuffer.lpcszHeader		= lpszHeaders;
			inbuffer.dwHeadersLength	= lpszHeaders? lstrlen(lpszHeaders) : 0;
			inbuffer.dwHeadersTotal		= lpszHeaders? lstrlen(lpszHeaders) : 0;
			inbuffer.lpvBuffer			= (void *)pPostData;
			inbuffer.dwBufferLength		= nLen;
			inbuffer.dwBufferTotal		= nLen;
			if (!HttpSendRequestEx(hRequest, &inbuffer, NULL, 0, 0))
				break;
			if (!HttpEndRequest(hRequest, NULL, 0, 0))
				break;
		} 
		else
		{
			if (!HttpSendRequest(hRequest, lpszHeaders, lpszHeaders ? -1 : 0, NULL, 0))
				break;
		}

		FILE *fp;
		fp=fopen(zipname, "wb+");	
		int byteWrite = 0;
		DWORD dwReadBytes = 0;
		DWORD dwStatusCode = -1;
		while (InternetReadFile(hRequest, buf, sizeof(buf), &dwReadBytes))
		{
			byteWrite = fwrite(buf,sizeof(char),dwReadBytes,fp);

			if (dwStatusCode == -1)
			{
				DWORD dwData = 0;
				DWORD dwDataLen = sizeof(dwData);

				if (HttpQueryInfo(hRequest, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &dwData, &dwDataLen, NULL))
					dwStatusCode = dwData;
				else
					assert(0);
			}

			if (dwReadBytes == 0) 
			{
				bRet = TRUE;	
				fclose(fp);
				return true;      
			}
	    	strResult.append(buf, dwReadBytes);
		}
			//fclose(fp);
	} while (0);

	if (hRequest)
		InternetCloseHandle(hRequest);
	if (hConnect)
		InternetCloseHandle(hConnect);
	if (hOpen) 
		InternetCloseHandle(hOpen);

	return bRet;

}

HttpFile::~HttpFile()
{
	for (int i = 0; i<10; i++)
	{
		for (int j = 0; j<3; j++)
		{
			delete []u_url[i].zipurl[j];
		}
	}
}
 
 

你可能感兴趣的:(利用Internet协议实现各种文件的下载)