分享
 
 
 

Http文件下载类源代码

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

// HttpClient.h: HTTP协议客户端的实现类

//

//////////////////////////////////////////////////////////////////////

#if !defined(_HTTPCLIENT_H__)

#define _HTTPCLIENT_H__

#include "../comm/tcp.h"

#pragma warning(disable : 4786)

#include <map>

#include <string>

using namespace std;

#define BUFFER_SIZE 8192

#define HEADS_BUFFER_SIZE 2048

#define PEEK_SIZE 500

#define TCP_TIMEOUT 5

class CHttpClient

{

public:

void Cancel();

const char* GetStatusString();

CHttpClient();

virtual ~CHttpClient();

bool Download(char* url,char* fname); //直接下载到文件

bool Download(char* url,HWND hParent,long msg = WM_USER+1); //消息方式下载数据流

inline long Instr(char* from,char* find);

virtual void OnDataRecived(char* data,long datasize,int first = false );

long GetHostName(char *url, char *buf);

int GetStatus();

long GetHeader(char* headname,char* buf);

long GetHeader(char* from,char* searchfor,char* buf);

bool Reset();

private:

long m_Message;

HWND m_hParent;

bool m_noCancel;

char m_fname[BUFFER_SIZE];

int m_status;

char m_heads_buffer[HEADS_BUFFER_SIZE];

char m_buffer[BUFFER_SIZE+1];

CTcp tcp;

map<const int,string> m_map;

};

#endif

//----------------------------------------------------------------

// HttpClient.cpp: implementation of the CHttpClient class.

//

//////////////////////////////////////////////////////////////////////

#include "stdafx.h"

#include "HttpClient.h"

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[]=__FILE__;

#define new DEBUG_NEW

#endif

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

CHttpClient::CHttpClient()

{

Reset();

memset(m_fname,0,BUFFER_SIZE);

tcp.init();

m_map[100]= "Continue";

m_map[101]= "Switching Protocols";

m_map[200]= "OK";

m_map[201]= "Created";

m_map[202]= "Accepted";

m_map[203]= "Non-Authoritative Information";

m_map[204]= "No Content";

m_map[205]= "Reset Content";

m_map[206]= "Partial Content";

m_map[300]= "Multiple Choices";

m_map[301]= "Moved Permanently";

m_map[302]= "Found";

m_map[303]= "See Other";

m_map[304]= "Not Modified";

m_map[305]= "Use Proxy";

m_map[307]= "Temporary Redirect";

m_map[400]= "Bad Request";

m_map[401]= "Unauthorized";

m_map[402]= "Payment Required";

m_map[403]= "Forbidden";

m_map[404]= "Not Found";

m_map[405]= "Method Not Allowed";

m_map[406]= "Not Acceptable";

m_map[407]= "Proxy Authentication Required";

m_map[408]= "Request Time-out";

m_map[409]= "Conflict";

m_map[410]= "Gone ";

m_map[411]= "Length Required";

m_map[412]= "Precondition Failed";

m_map[413]= "Request Entity Too Large";

m_map[414]= "Request-URI Too Large";

m_map[415]= "Unsupported Media Type";

m_map[416]= "Requested range not satisfiabl";

m_map[417]= "Expectation Failed";

m_map[500]= "Internal Server Error";

m_map[501]= "Not Implemented";

m_map[502]= "Bad Gateway";

m_map[503]= "Service Unavailable";

m_map[504]= "Gateway Time-out";

m_map[505]= "HTTP Version not supported";

}

CHttpClient::~CHttpClient()

{

}

bool CHttpClient::Reset()

{

m_noCancel=true;

m_hParent=NULL;

m_Message=0;

memset(m_buffer,0,BUFFER_SIZE);

memset(m_heads_buffer,0,HEADS_BUFFER_SIZE);

return 1;

}

//HTTP下载主程序

bool CHttpClient::Download(char *url, HWND hParent,long msg)

{

m_Message=m_Message;

m_hParent=hParent;

//状态为忙

Reset();

char hostname[256];

memset(hostname,0,256);

GetHostName(url,hostname);

long AllSize=0;

long ReadSize=0;

bool headFinished=false;

int s;

s=tcp.connect(hostname,80,TCP_TIMEOUT,1);

if(s<0)

return false;

sprintf(m_buffer,"GET %s HTTP/1.0 \r\nHost:%s\r\nAccept:*/*\r\nUser-Agent: AutoUpdate/1.0 \r\n\r\n",url,hostname);

tcp.send(s,m_buffer,strlen(m_buffer),TCP_TIMEOUT);

//先取PEEK_SIZE个字节,这样可以确保取到Content-Length

ReadSize=tcp.recv(s,m_buffer,PEEK_SIZE,TCP_TIMEOUT);

if(ReadSize==-1)

return false;

m_buffer[ReadSize]=0;

memset(hostname,0,256);

int m,n;

m=Instr(m_buffer," ");

n=Instr(m_buffer+m+1," ");

memcpy(hostname,m_buffer+m+1,n);

m_status=atoi(hostname);

if(m_status!=200)return false;

memset(hostname,0,256);

if(GetHeader(m_buffer,"Content-Length",hostname)<0)

return false;

//取得内容总长度

AllSize=atol(hostname);

memset(hostname,0,256);

//寻找HTTP数据区表示

int i;

i=Instr(m_buffer,"\r\n\r\n");

if(i>0)

{

memcpy(m_heads_buffer,m_buffer,i+4);

headFinished=true;

ReadSize=ReadSize-i-4;

OnDataRecived(m_buffer+i+4,ReadSize,true);

}

while(ReadSize<AllSize && m_noCancel)

{

int nSize;

if(headFinished)

{

nSize=(AllSize-ReadSize)>BUFFER_SIZE?BUFFER_SIZE:(AllSize-ReadSize);

memset(m_buffer,0,BUFFER_SIZE);

if(tcp.recv(s,m_buffer,nSize,TCP_TIMEOUT)!=nSize)

return false;

ReadSize+=nSize;

m_buffer[nSize]=0;

OnDataRecived(m_buffer,nSize);

}

else

{

nSize=(AllSize-ReadSize)>(BUFFER_SIZE-ReadSize)?(BUFFER_SIZE-ReadSize):(AllSize-ReadSize);

if(tcp.recv(s,m_buffer+ReadSize,nSize,TCP_TIMEOUT)!=nSize)

return false;

ReadSize+=nSize;

m_buffer[nSize]=0;

//寻找HTTP数据区表示

i=Instr(m_buffer,"\r\n\r\n");

if(i>0)

{

memcpy(m_heads_buffer,m_buffer,i+4);

headFinished=true;

ReadSize=ReadSize-i-4;

OnDataRecived(m_buffer+i+4,ReadSize,true);

}

}

}

if(!m_noCancel)remove(m_fname);

tcp.close(s);

return true;

}

int CHttpClient::GetStatus()

{

return m_status;

}

//从URL中取出主机名

long CHttpClient::GetHostName(char *url, char *buf)

{

int i,j;

char* lpsz = _tcsstr(url, "//");

if(!lpsz)return -1;

i=lpsz-url+2;

lpsz= _tcsstr(url+i, "/");

if(!lpsz)return -1;

j=lpsz-url;

memcpy(buf,url+i,j-i);

return j-i;

}

long CHttpClient::GetHeader(char *headname, char *buf)

{

return GetHeader(m_heads_buffer,headname,buf);

}

long CHttpClient::GetHeader(char *from, char *headname, char *buf)

{

char *p;

char* lpsz = _tcsstr(from, headname);

if(!lpsz)return -1;

//lpsz++;

p=lpsz+strlen(headname)+2;

lpsz = _tcsstr(p, "\r\n");

if(!lpsz)return -1;

memcpy(buf,p,lpsz-p);

return strlen(buf);

}

void CHttpClient::OnDataRecived(char* data,long datasize ,int first)

{

if(m_hParent)

::SendMessage(m_hParent,m_Message,(unsigned int)data,datasize);

else

{

if(first)remove(m_fname);

FILE* f=fopen(m_fname,"ab");

if(f){

fwrite(data,1,datasize,f);

fclose(f);

}

}

//处理数据,一定要拷贝走哦,缓冲区可是循环使用的

}

inline long CHttpClient::Instr(char *from, char *find)

{

char* lpsz = _tcsstr(from, find);

return (!lpsz)?-1:lpsz-from;

}

bool CHttpClient::Download(char *url, char *fname)

{

strcpy(m_fname,fname);

return Download(url,NULL,NULL);

}

const char* CHttpClient::GetStatusString()

{

return m_map[m_status].c_str();

}

void CHttpClient::Cancel()

{

m_noCancel=false;

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有