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 ...
随机推荐
- 使用C#和MSMQ开发消息处理程序
简介 MSMQ(微软消息队列)是Windows操作系统中消息应用程序的基础,是用于创建分布式.松散连接的消息通讯应用程序的开发工具.消息队列和电子邮件有着很多相似处,他们都包含多个属性,用于保存消息, ...
- 寻找高边电流IC
因为项目需要,无法使用地的电流检测,需要使用高边的电流检测 IC. 搜索的关键字: 高边 电流 高侧 电流 目前找到以下几款: INA199A1,来自参考方案,属于宽电压输入的. INA180B4ID ...
- centos6 ext4修复
输入root密码后: fsck -y /dev/mapper/vg_logserv-lv_root 修复完后重启 reboot 若忘记了root密码,可用系统ISO盘引导进入Rescue救援模式 在这 ...
- windows 安装操作系统时切换分区表格式
在出现分区管理界面时,按下shift+F10呼出命令行,输入diskpart 后尝试如下命令将磁盘分区表手动转换到MBR. list disk ---- 显示当前磁盘列表 select disk x ...
- Apache Shiro在web开发安全框架中的应用
前阶段就hadoop的分享了一些内容,希望对新手入门的朋友有点帮助吧!对于hadoop新手入门的,还是比较推荐大快搜索的DKHadoop发行版,三节点标准版还是值得拥有的(三节点的标准版是可以免费下载 ...
- 一个最简的Thinkphp3.2 操作Mongodb的例子
看到Thinkphp网站上没有调用Mongodb的例子,就写一个一个最简的Thinkphp操作Mongodb的例子.欢迎讨论[前提]Thinkphp对Mongdb的支持依赖于PHP对Mongodb的支 ...
- python之BeautifulSoup4的例子
仅作演示用 from bs4 import BeautifulSoup import urllib.request webfile = urllib.request.urlopen('http://w ...
- PHP中imagecopyresampled参数详解
原文链接http://blog.csdn.net/ajaxchen_615/article/details/5941181 做php缩微图程序,用到了imagecopyresampled函数,在网上找 ...
- android 更新listview 其中一行的数据显示
private void updateView(int index){ View v = yourListView.getChildAt(index - yourListView.getFirstVi ...
- Maven下载cxf所需要的jar包
<dependency> <groupId>org.codehaus.woodstox</groupId> <artifactId>woodstox-c ...