有一个控制下载的管理类吧,调用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() 获取下载的进度以用于其它目的。

NDK开发中的一个HTTP下载实例附带下载进度的更多相关文章

  1. C#开发中使用Npoi操作excel实例代码

    C#开发中使用Npoi操作excel实例代码 出处:西西整理 作者:西西 日期:2012/11/16 9:35:50 [大 中 小] 评论: 0 | 我要发表看法 Npoi 是什么? 1.整个Exce ...

  2. 在C#/.NET应用程序开发中创建一个基于Topshelf的应用程序守护进程(服务)

    本文首发于:码友网--一个专注.NET/.NET Core开发的编程爱好者社区. 文章目录 C#/.NET基于Topshelf创建Windows服务的系列文章目录: C#/.NET基于Topshelf ...

  3. NDK 开发中,各种指令集的坑,arm64

          最近在NDK开发中遇到了一个奇怪的问题,希望记录下,可以帮到大家:         我编译了一些 .so 动态库,只编译了armeabi-v7a.armeabi 指令集,其它指令集编译不了 ...

  4. iPhone开发中从一个视图跳到另一个视图有三种方法:

    iPhone开发中从一个视图跳到另一个视图有三种方法:   1.self.view addSubView:view .self.window addSubView,需要注意的是,这个方法只是把页面加在 ...

  5. MVC已经是现代Web开发中的一个很重要的部分,下面介绍一下Spring MVC的一些使用心得。

    MVC已经是现代Web开发中的一个很重要的部分,下面介绍一下Spring MVC的一些使用心得. 之前的项目比较简单,多是用JSP .Servlet + JDBC 直接搞定,在项目中尝试用 Strut ...

  6. 在开发中进入一个方法后想要到原来那行 ctrl+alt+左 回到上一步 ctrl+alt+右 回到下一步

    在开发中进入一个方法后想要到原来那行 ctrl+alt+左 回到上一步ctrl+alt+右 回到下一步

  7. 项目开发中封装一个BarButtonItem类别-很实用

    Encapsulates a TabBarItem--封装一个BarButtonItem类 在我们程序的导航栏的左边或右边一般都会有这样的BarButtonItem,用来界面之间的跳转 如果我们有很多 ...

  8. Dynamics CRM - 在 Dynamics CRM 开发中创建一个 Entity 对象

    在 Dynamics CRM 的开发中,我们时不时需要创建 Entity 对象,而对于如何创建 Entity 对象,在 C# plugin 和 JS 的写法存在些许差异. 一.C# Plugin 创建 ...

  9. 在安卓开发中使用SQLite数据库操作实例

    前段时间写了个安卓平台下SQLite数据库操作的实例 ,一直没得时间总结 ,今天把它弄出来了. 在Android 运行时环境包含了完整的 SQLite. 首先介绍一下SQLite这个数据库: SQLi ...

随机推荐

  1. restheart 基本使用

    restheart 是一个方便基于mongodb的restapi 开发框架 参考项目 https://github.com/rongfengliang/restheart-docker-compose ...

  2. Aria2+yaaw+Chrome插件BaiduExporter实现百度网盘下载

    Aria2+yaaw+Chrome插件BaiduExporter实现百度网盘下载 这篇博客主要为了解决百度网盘下载限速以及linux等操作系统无百度客户端的问题.主要包括两个方面第一个是aria2的安 ...

  3. FastAdmin 插件的 Git 开发流程(简明)

    FastAdmin 插件的 Git 开发流程(简明) cms zip 安装 包安装 删除 addons 里的 cms 使用 mklink 软链接到 cms 插件 Git 仓库 修改 cms 插件 gi ...

  4. FastAdmin 开发第三天:安装 FastAdmin

    环境安装安装好后就可以安装 FastAdmin 了. 根据文档说明安装步骤如下,推荐使用命令行安装: 克隆FastAdmin到你本地 git clone https://git.oschina.net ...

  5. 如何使用button在tab中新建打开一个链接页

    在APPBOX某页中如何使用button按钮打开一个新的链接页.比如说百度.谷歌等 在后台的单击事件中使用以下语句即            string url = "DownloadIma ...

  6. Java awt组件间的继承关系

    Container的继承关系: Window是可独立存在的容器,其他则不行.

  7. Microsoft Dynamics CRM 4.0 Plugin 取值,赋值,查询

    DynamicEntity postImageEntity = (DynamicEntity)context.PostEntityImages["PostImage"]; if ( ...

  8. Asp.Net中使用Newtonsoft.Json转换,读取,写入

    using Newtonsoft.Json;using Newtonsoft.Json.Converters; //把Json字符串反序列化为对象目标对象 = JsonConvert.Deserial ...

  9. make dep

    在配置好内核后就是编译内核了,在编译之前首先应该执行make dep命令建立好依赖关系,该命令将会修改linux中每个子目录下的.depend文件,该文件包含了该目录下每个目标文件所需要的头文件(绝对 ...

  10. 终于完成了 源码 编译lnmp环境

    经过了大概一个星期的努力,终于按照海生的编译流程将lnmp环境源码安装出来了 nginx 和php 主要参考 http://hessian.cn/p/1273.html mysql 主要参考 http ...