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() 获取下载的进度以用于其它目的。
NDK开发中的一个HTTP下载实例附带下载进度的更多相关文章
- C#开发中使用Npoi操作excel实例代码
C#开发中使用Npoi操作excel实例代码 出处:西西整理 作者:西西 日期:2012/11/16 9:35:50 [大 中 小] 评论: 0 | 我要发表看法 Npoi 是什么? 1.整个Exce ...
- 在C#/.NET应用程序开发中创建一个基于Topshelf的应用程序守护进程(服务)
本文首发于:码友网--一个专注.NET/.NET Core开发的编程爱好者社区. 文章目录 C#/.NET基于Topshelf创建Windows服务的系列文章目录: C#/.NET基于Topshelf ...
- NDK 开发中,各种指令集的坑,arm64
最近在NDK开发中遇到了一个奇怪的问题,希望记录下,可以帮到大家: 我编译了一些 .so 动态库,只编译了armeabi-v7a.armeabi 指令集,其它指令集编译不了 ...
- iPhone开发中从一个视图跳到另一个视图有三种方法:
iPhone开发中从一个视图跳到另一个视图有三种方法: 1.self.view addSubView:view .self.window addSubView,需要注意的是,这个方法只是把页面加在 ...
- MVC已经是现代Web开发中的一个很重要的部分,下面介绍一下Spring MVC的一些使用心得。
MVC已经是现代Web开发中的一个很重要的部分,下面介绍一下Spring MVC的一些使用心得. 之前的项目比较简单,多是用JSP .Servlet + JDBC 直接搞定,在项目中尝试用 Strut ...
- 在开发中进入一个方法后想要到原来那行 ctrl+alt+左 回到上一步 ctrl+alt+右 回到下一步
在开发中进入一个方法后想要到原来那行 ctrl+alt+左 回到上一步ctrl+alt+右 回到下一步
- 项目开发中封装一个BarButtonItem类别-很实用
Encapsulates a TabBarItem--封装一个BarButtonItem类 在我们程序的导航栏的左边或右边一般都会有这样的BarButtonItem,用来界面之间的跳转 如果我们有很多 ...
- Dynamics CRM - 在 Dynamics CRM 开发中创建一个 Entity 对象
在 Dynamics CRM 的开发中,我们时不时需要创建 Entity 对象,而对于如何创建 Entity 对象,在 C# plugin 和 JS 的写法存在些许差异. 一.C# Plugin 创建 ...
- 在安卓开发中使用SQLite数据库操作实例
前段时间写了个安卓平台下SQLite数据库操作的实例 ,一直没得时间总结 ,今天把它弄出来了. 在Android 运行时环境包含了完整的 SQLite. 首先介绍一下SQLite这个数据库: SQLi ...
随机推荐
- Oracle:Decode在时间范围中的使用
做查询的时候需要下一个sql,需要select test_time出来,如果test_Time的HH24:Mi:SS在7:00:00和19:00:00返回白班,否则返回夜班 select case w ...
- java 中一些需要注意的知识点
java数组的length属性是容量,而不是数组真实元素的个数: 多线程中的interrupt()方法并不会终止处于"运行状态"的线程,它只是将线程的中断标记设为true. juc ...
- Asp.Net Core MVC框架内置过滤器
第一部分.MVC框架内置过滤器 下图展示了Asp.Net Core MVC框架默认实现的过滤器的执行顺序: Authorization Filters:身份验证过滤器,处在整个过滤器通道的最顶层.对应 ...
- ASP.NET中将数据作为XML数据发送 使用 Request.InputStream 接收
将数据作为XML数据发送,例如:public void PostXml(string url, string xml){byte[] bytes = Encoding.UTF8.GetBytes(xm ...
- 织梦调用文章 ID (来源:百度知道)
问:{dede:field.id /} {dede:channel type='son' orderby='sortrank'} <a href='[field:typeurl/]'>&l ...
- TraceView 使用详解 android eclipse
先看命令 (配置好环境变量的情况下,直接traceview+空格+ trace文件路径即可): TraceView是什么 Traceview是android平台配备一个很好的性能分析的工具.它可以通过 ...
- BASIC-25_蓝桥杯_回形取数
示例代码: #include <stdio.h>#define N 200 int main(void){ int num[N][N]; int i= 0, j = 0 , k = 0 , ...
- 在VS2013平台下如何快速解决c++代码内存泄漏问题
在学习FPS3000人脸关键点定位算法时,发现github上的源码,存在大量的内存泄漏问题,在训练的时发现内存一直在增长,测试的时候也存在内存无法彻底释放的问题. 一直以为是存放模型参数vector& ...
- 5.验证用户名是否已经被注册:AJAXC请求
首先在 web.xml 文件中添加配置信息 <!-- 配置全局的字符集 --> <context-param> <param-name>encode</par ...
- 手贱,写个call玩玩.
今天在睡觉醒时,突然感觉对call和apply有了点理解,但是又不好表达出来.就随便写几个例子. function say() { return this.role; } function Fathe ...