自己封装了一个文件下载的类,适合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;
}
}