有一个控制下载的管理类吧,调用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. yugabyte 集成JanusGraph测试

    yugabyte 集成图数据库JanusGraph,原理比较简单就是yugabyte 内置Cassandra,配置好JanusGraph 的访问就可以了. 使用docker 模式部署 创建yugaby ...

  2. 如何判断一个请求是否为AJAX请求

    普通请求与ajax请求的报文头不一样,通过如下 String requestType = request.getHeader("X-Requested-With");  如果req ...

  3. 【转】每天一个linux命令(61):wget命令

    原文网址:http://www.cnblogs.com/peida/archive/2013/03/18/2965369.html Linux系统中的wget是一个下载文件的工具,它用在命令行下.对于 ...

  4. uml 知识点

    Unified Modeling Language (UML)又称统一建模语言或标准建模语言

  5. JMeter和JMeterPlugin的下载安装

    JMeter和JMeterPlugin的下载安装 Apache Jmeter是一个100%的纯Java桌面应用,主要是针对web的压力和性能测试,但后来扩展到其他测试领域.Jmeter可以用于测试FT ...

  6. dkh人力资源大数据解决方案整体架构

    大数据技术的应用正在潜移默化改变着我们的日常生活习惯和工作方式,很多看起来有点“不可思议”的事情也渐渐被我们“习以为常”.大数据可能在国内的起步较晚,但我们可能却是对大数据应用最好的了代表了.前些时候 ...

  7. 理解REST和SOA

    REST -- REpresentational State Transfer 直接翻译:表现层状态转移. 精辟理解:URL定位资源,用HTTP动词(GET,POST,DELETE,DETC)描述操作 ...

  8. JZ2440 裸机驱动 第8章 NAND Flash控制器

    本章目标  了解NAND Flash 芯片的接口 掌握通过NAND Flash控制器访问NAND Flash的方法 8.1 NAND Flash介绍和NAND Flash控制器使用     NAND ...

  9. WPF Demo4

    <Window x:Class="Demo4.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/ ...

  10. java工具类-excel jxl

    jxl-2.6.9.14.jarimport net.sf.jxls.transformer.XLSTransformer;//jxls-core-1.0.2.jarimport java.io.Fi ...