NDK开发中的一个HTTP下载实例附带下载进度

有一个控制下载的管理类吧,调用http下载类进行各种下载,同时在下载过程中可以显示其下载的进度,而且在每个下载结束之后以类似回调的方式告诉管理类,以继续进行后续的操作。

直接代码:

.h文件

 #pragma once
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#include <iostream>
#include <string.h>
#include <unistd.h>
#include <fstream>
#include <vector>
#include <pthread.h>
#include <android/log.h>
using namespace std; class CHttpDownLoad
{
public:
CHttpDownLoad(void);
~CHttpDownLoad(void); public:
void   DownLoad(string str1,string str2,string str3,void* handler);
int GetDownState();
private:
int GetFileSize(const char* host,const char* file,string* error,int& headersize); public:
string m_strIP;
string m_strFileName;
string m_strLocFile ;
float m_filesize ;
int m_hsize;
int m_iProgress;
void *m_pUdateBase;
};

.cpp文件

 #include "stdafx.h"
#include "CHttpDownLoad.h"
#include <stdlib.h>
#include "updateBase.h" typedef string::size_type (string::*find_t)(const string& delim,string::size_type offset) const; vector<string> Split(const string& s,const string& match,bool removeEmpty=false,bool fullMatch=false)
{
vector<string> result;
string::size_type start = , skip = ;
find_t pfind = &string::find_first_of;
if (fullMatch)
{
skip = match.length();
pfind = &string::find;
}
while (start != string::npos)
{
string::size_type end = (s.*pfind)(match, start);
if (skip == ) end = string::npos;
string token = s.substr(start, end - start);
if (!(removeEmpty && token.empty()))
{
result.push_back(token);
}
if ((start = end) != string::npos) start += skip;
} return result;
} void SplitProperty(vector<string> property,string* name,string *value)
{
vector<string>::iterator it=property.begin();
if(it!= property.end())
{
name->clear();
name->append(*it);
}
it++;
if(it!= property.end())
{
value->clear();
value->append(*it);
}
} CHttpDownLoad::CHttpDownLoad(void)
{
m_filesize = ;
m_hsize = ;
m_iProgress = ;
m_pUdateBase = NULL;
} CHttpDownLoad::~CHttpDownLoad(void)
{
} void DownloadFile(const char* host,
const char* file,
const char * savefile,
float size,int hsize,
int& progress,
updateBase* handler
)
{
struct sockaddr_in servaddr;
struct hostent *hp;
string info;
int sock_id;
//char message[18000] = {0};
char *message = new char[];
memset(message,,);
//char messagetop[18000]={0};
char *messagetop = new char[];
memset(messagetop,,);
int msglen;
float readcount=;
string request;
request.append("GET ");
request.append(file);
request.append(" HTTP/1.1\n");
request.append("Host:");
request.append(host);
request.append("\r\n\r\n");
if((sock_id = socket(AF_INET, SOCK_STREAM, )) == -)
{
return;
}
memset(&servaddr,,sizeof(servaddr));
if((hp = gethostbyname(host)) == NULL)
{
return;
}
memcpy((char *)&servaddr.sin_addr.s_addr, (char *)hp->h_addr, hp->h_length);
servaddr.sin_port = htons();
servaddr.sin_family = AF_INET;
if(connect(sock_id, (struct sockaddr *)&servaddr, sizeof(servaddr)) != )
{
return;
}
write(sock_id,request.c_str(),request.length());
ofstream outfile (savefile,ofstream::binary);
do{
msglen = read(sock_id,message,);
if(msglen==)
{
break;
} if(readcount==)
{
int tempindex=;
//for(int i =hsize - 1;i<msglen;i++)
for(int i =hsize;i<msglen;i++)
{
messagetop[tempindex]= message[i];
tempindex=tempindex+;
}
outfile.write (messagetop,tempindex);
}
else
{
outfile.write (message,msglen);
}
readcount=readcount+msglen;
progress = readcount/size*;
}while(readcount<=(size+ hsize));
outfile.close();
close(sock_id); if (message != NULL)
{
delete[] message;
message = NULL;
}
if (messagetop != NULL)
{
delete[] messagetop;
messagetop = NULL;
} handler->CallupdateBaseFinsh();//回调下载结束 } void* UpdateWorCoping(void* data)
{
CHttpDownLoad *pGhttpFile = (CHttpDownLoad*)data;
DownloadFile(pGhttpFile->m_strIP.c_str(),
pGhttpFile->m_strFileName.c_str(),
pGhttpFile->m_strLocFile.c_str(),
pGhttpFile->m_filesize,
pGhttpFile->m_hsize,
pGhttpFile->m_iProgress,
(updateBase*)pGhttpFile->m_pUdateBase
); return ((void*));
} int CHttpDownLoad::GetFileSize(const char* host,const char* file,string* error,int& headersize)
{
int size=-;
struct sockaddr_in servaddr;
struct hostent *hp;
string splitline="\r\n";
string PName;
string PValue;
string splittagbalue=":";
string info;
vector<string> properties;
vector<string> property;
int sock_id;
//char message[1024*1024] = {0};
char *message = new char[*];
memset(message,,*);
int msglen;
string request;
request.append("HEAD ");
request.append(file);
request.append(" HTTP/1.1\n");
request.append("Host:");
request.append(host);
request.append("\r\n\r\n");
if((sock_id = socket(AF_INET, SOCK_STREAM, )) == -)
{
error->append("Couldn't get a socket!");
return size;
}
memset(&servaddr,,sizeof(servaddr)); if((hp = gethostbyname(host)) == NULL)
{
error->append("Couldn't access network.");
error->append(host);
return size;
}
memcpy((char *)&servaddr.sin_addr.s_addr, (char *)hp->h_addr, hp->h_length);
servaddr.sin_port = htons();
servaddr.sin_family = AF_INET;
if(connect(sock_id, (struct sockaddr *)&servaddr, sizeof(servaddr)) != )
{
error->append("Couldn't connect!");
return size;
}
write(sock_id,request.c_str(),request.length());
msglen = read(sock_id,message,*);
headersize= msglen;
info.append(message,,msglen);
close(sock_id);
properties =Split(info,splitline,true);
vector<string>::iterator it;
for (it=properties.begin(); it<properties.end(); it++)
{
property= Split(*it,splittagbalue,true);
SplitProperty(property,&PName,&PValue);
if(PName=="Content-Length")
{
size =atoi(PValue.c_str());
break;
}
}
if(size==-)
{
error->append("Resource Not Found!");
} if (message!=NULL)
{
delete[] message;
message = NULL;
}
return size; } //给出的这样一个完整的url :"http://10.10.41.112/ressdir/test/111111111.lst"
//对应下面几个参数为:(注意格式)
//str1 = "10.10.41.112";
//str2 = "//ressdir//test//111111111.lst";
//str3 = "/mnt/sdcard/test/111111111.lst"; void CHttpDownLoad::DownLoad(string str1,string str2,string str3,void *handler)
{
if (str1.empty()||str2.empty()||str3.empty()||handler == NULL)
{
LOGI("0___DownLoad is error!!!");
return;
} m_strIP = str1;
m_strFileName= str2;
m_strLocFile = str3;
m_pUdateBase = handler; string error;
m_filesize = GetFileSize(str1.c_str(),str2.c_str(),&error,m_hsize);
if (m_filesize<=)
{
LOGI("1_____DownLoad is error!!!");
return;
} pthread_t thread_id;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
pthread_create(&thread_id,&attr,UpdateWorCoping,this); m_thread_id = thread_id;
pthread_attr_destroy(&attr);
} int CHttpDownLoad::GetDownState()
{
return m_iProgress;//用于下载进度
}

其中 updateBase 就是那个下载管理类,这里就不在贴出了。

在管理类中调用 DownLoad(string str1,string str2,string str3,void *handler);//此处主要格式,handler参数为下载管理类指针用于下载结束的回调

理进行http下载。

在下载过程中调用 GetDownStae() 获取下载的进度以用于其它目的。

上一篇:js面试题知识点全解(一原型和原型链1)


下一篇:定时器同步+触发三ADC采样+输出6路PWM波