自己封装了一个socket下载文件的类

本文介绍了一个自封装的HTTP文件下载类,适用于Content-Length类型的文件下载。文章提供了详细的类实现代码,包括初始化套接字、连接服务器、发送HTTP请求、接收头部及数据等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自己封装了一个文件下载的类,适合Content-Length文件的下载,至于Transfer-Encoding形势的自行修改
以下代码是vs.net 2003测试通过
SockHttp.hpp
#pragma once
#include "stdio.h"
#include <winsock2.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "string.h"

#pragma comment(lib,"ws2_32")
class CSockHttp
{
public:
	CSockHttp(void);
	CSockHttp(const char* url);
	~CSockHttp(void);
	bool InitSock();
	bool ConnectSv();
	bool SendHttpRes();
	bool RecvHeadAndData();
	bool RecvFile(const char* PathAndName);
	void getData(char* buf);
	int ResolveUrl(char *Website, char *Path, char *FileName, const char *sUrl);
private:
	char m_data[5000];
	char m_strlength[512];
	//char m_Url[512];         //"http://192.168.1.58/adcloudsdk/md5.php";//"http://192.168.1.58/adcloudsdk/ad_cloud_sdk_cpp.dll";
	char m_Website[512];
	char m_Path[256];
	char m_FileName[256];
	char m_request[512];
	char m_firstpaket[5000];
	char m_createfile[256];
	int  m_filelength,m_revlength,m_firstlength;
	struct hostent *m_hptr;
	FILE *fp;
	SOCKET m_sClient;
};
<pre name="code" class="cpp">SockHttp.cpp
#include ".\sockhttp.h"


CSockHttp::CSockHttp(void)
{
}
CSockHttp::CSockHttp(const char* url){
//strcpy(m_Url,url);
memset(m_Website,0,sizeof(m_Website));
memset(m_Path,0,sizeof(m_Path));
ResolveUrl(m_Website,m_Path,m_FileName,url);
InitSock();
ConnectSv();
SendHttpRes();
}
CSockHttp::~CSockHttp(void)
{
closesocket(m_sClient);   
}
bool CSockHttp::InitSock(){
WSADATA wsaData;
WORD sockVersion = MAKEWORD(2, 2);
if(WSAStartup(sockVersion, &wsaData)){
return false;
}


if((m_hptr = gethostbyname(m_Website)) == NULL)
{
printf("gethostbyname error for host\n");
return false; /* 如果调用gethostbyname发生错误,返回 */
}
m_sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(m_sClient == INVALID_SOCKET){
return false;
}
return true;
}


bool CSockHttp::ConnectSv(){
sockaddr_in servAddr;
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(80);
servAddr.sin_addr = *(struct in_addr*)m_hptr->h_addr_list[0];
if(connect(m_sClient,(sockaddr*)&servAddr,sizeof(servAddr))==-1){
return false;
}
return true;
}


bool CSockHttp::SendHttpRes(){
wsprintf(m_request,"GET %s HTTP/1.1\r\n"
"Accept: */*\r\n"
"Accept-Language: zh-cn\r\n"
"Host: %s\r\n"
"Connection: Keep-Alive\r\n\r\n",m_Path,m_Website);
if(send(m_sClient,m_request,strlen(m_request),0) < 0){
return false;
}
return true;
}
bool CSockHttp::RecvHeadAndData(){
int ret = 0;
memset(m_data,0,5000);
ret = recv(m_sClient,m_data,5000,0);
//if(ret > 0){
// printf("%s\n",m_data);
// printf("-----------------return massage length:%d-------------\n",strlen(m_data));
//}
if(strstr(m_data,"Content-Length: ")!=NULL)
{
strcpy(m_strlength,strstr(m_data,"Content-Length: ")+16);
m_filelength=atoi(m_strlength);
//printf("filelength(to int) : %d \n",m_filelength);
}
strcpy(m_createfile,"");
strcat(m_createfile,m_FileName);
fp=fopen(m_createfile,"wb");
if(fp!=NULL)
{
printf("create file ok! \n");
}else{
return false;
}
int i = 0;
while(i<ret)
{
if(m_data[i]=='\r' && m_data[i+1]=='\n' && m_data[i+2]=='\r' && m_data[i+3]=='\n')
{
m_firstlength=i+3;
//printf("m_firstlength= % d --i=%d--%x--%x--%x--%x--m_data[ret]:%x--\n",m_firstlength,i,m_data[i],m_data[i+1],m_data[i+2],m_data[i+3],m_data[ret]);
break;
}
i++;
}
strcpy(m_firstpaket,m_data+m_firstlength+1);
m_revlength = 0;
if(m_firstlength<ret){
m_revlength = ret - m_firstlength-1;
while(m_firstlength+1<ret)
{
fputc(m_data[m_firstlength+1],fp);
m_firstlength++;
}
}


ret=0;
while(m_revlength<m_filelength)
{
memset(m_data,0x00,5000);
ret = recv(m_sClient,m_data,5000,0);
m_revlength=m_revlength+ret;
//if(ret>0)
//{
// printf("\r");
// printf("========download size: %d  byte",m_revlength);


//}
fwrite(m_data,ret,1,fp);
}


printf("\n download ok!\n");
fclose(fp);
fp = NULL;
return true;
}


bool CSockHttp::RecvFile(const char* PathAndName){
int ret = 0;
memset(m_data,0,5000);
ret = recv(m_sClient,m_data,5000,0);


if(strstr(m_data,"Content-Length: ")!=NULL)
{
strcpy(m_strlength,strstr(m_data,"Content-Length: ")+16);
m_filelength=atoi(m_strlength);
//printf("filelength(to int) : %d \n",m_filelength);
}
if(!PathAndName){
strcpy(m_createfile,m_Path);
}else{
strcpy(m_createfile,PathAndName);
}

//strcat(m_createfile,m_FileName);
fp=fopen(m_createfile,"wb");
if(fp!=NULL)
{
//printf("create file ok! \n");
}else{
return false;
}
int i = 0;
while(i<ret)
{
if(m_data[i]=='\r' && m_data[i+1]=='\n' && m_data[i+2]=='\r' && m_data[i+3]=='\n')
{
m_firstlength=i+3;
//printf("m_firstlength= % d --i=%d--%x--%x--%x--%x--m_data[ret]:%x--\n",m_firstlength,i,m_data[i],m_data[i+1],m_data[i+2],m_data[i+3],m_data[ret]);
break;
}
i++;
}
strcpy(m_firstpaket,m_data+m_firstlength+1);
m_revlength = 0;
if(m_firstlength<ret){
m_revlength = ret - m_firstlength-1;
while(m_firstlength+1<ret)
{
fputc(m_data[m_firstlength+1],fp);
m_firstlength++;
}
}


ret=0;
while(m_revlength<m_filelength)
{
memset(m_data,0x00,5000);
ret = recv(m_sClient,m_data,5000,0);
m_revlength=m_revlength+ret;
fwrite(m_data,ret,1,fp);
}


//printf("\n download ok!\n");
fclose(fp);
fp = NULL;               


return true;
}


void CSockHttp::getData(char* buf){
DWORD start =  GetTickCount(); 
int ret = 0;
memset(m_data,0,5000);
ret = recv(m_sClient,m_data,5000,0);


strcpy(m_createfile,""); 
strcat(m_createfile,m_FileName);
//fp=fopen(m_createfile,"wb");


int i = 0;
while(i<ret)
{
if(m_data[i]=='\r' && m_data[i+1]=='\n' && m_data[i+2]=='\r' && m_data[i+3]=='\n')
{
m_firstlength=i+3;
break;
}
i++;
}
strcpy(buf,m_data+m_firstlength+1);


//fclose(fp);
//fp = NULL;        
//strcpy(buf,m_data+m_firstlength+1);
DWORD stop = GetTickCount();
printf("getdata:%ld\n",stop-start);
/*strcpy(buf ,m_firstpaket);*/
return ;
}
int CSockHttp::ResolveUrl(char *Website, char *Path, char *FileName, const char *sUrl)
{
int UrlLength,WebsiteLength,i,Sign;
char Url[512] = {0};


if(strstr(sUrl,"http://") != NULL)
{
strcpy(Url,sUrl+7);
}
else
{
strcpy(Url,sUrl);
}


UrlLength = strlen(Url);


if(strstr(Url,"/") != NULL)
{
strcpy(Path, strstr(Url,"/"));
strncpy(Website,Url, UrlLength - strlen(strstr(Url,"/")));
for(i=0; i<UrlLength; i++)
{
if(Url[i] == '/')
{
Sign=i;
}
}
strcpy(FileName, Url + Sign+1);
return 0;
}
else
{
return 1;
}


}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值