zoukankan      html  css  js  c++  java
  • NDK开发中的一个HTTP下载实例附带下载进度

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

    直接代码:

    .h文件

     1 #pragma once
     2 #include <stdio.h>
     3 #include <sys/types.h>
     4 #include <sys/socket.h>
     5 #include <netinet/in.h>
     6 #include <netdb.h>
     7 #include <stdlib.h>
     8 #include <iostream>
     9 #include <string.h>
    10 #include <unistd.h>
    11 #include <fstream>
    12 #include <vector>
    13 #include <pthread.h>
    14 #include <android/log.h>
    15 using namespace std;
    16 
    17 
    18 class CHttpDownLoad
    19 {
    20 public:
    21     CHttpDownLoad(void);
    22     ~CHttpDownLoad(void);
    23 
    24 public:
    25     void      DownLoad(string str1,string str2,string str3,void* handler);
    26     int        GetDownState();
    27 private:
    28     int        GetFileSize(const char* host,const char* file,string* error,int& headersize);
    29 
    30     
    31 public:
    32     string        m_strIP;
    33     string        m_strFileName;
    34     string        m_strLocFile ;
    35     float        m_filesize ;
    36     int            m_hsize;
    37     int            m_iProgress;
    38     void        *m_pUdateBase;
    39 };

    .cpp文件

      1 #include "stdafx.h"
      2 #include "CHttpDownLoad.h"
      3 #include <stdlib.h>
      4 #include "updateBase.h"
      5 
      6 typedef string::size_type (string::*find_t)(const string& delim,string::size_type offset) const;
      7 
      8 vector<string> Split(const string& s,const string& match,bool removeEmpty=false,bool fullMatch=false)
      9 {
     10     vector<string> result;                       
     11     string::size_type start = 0, skip = 1;                  
     12     find_t pfind = &string::find_first_of;    
     13     if (fullMatch)        
     14     {            
     15         skip = match.length();           
     16         pfind = &string::find;        
     17     }        
     18     while (start != string::npos)        
     19     {            
     20         string::size_type end = (s.*pfind)(match, start);           
     21         if (skip == 0) end = string::npos;   
     22         string token = s.substr(start, end - start);   
     23         if (!(removeEmpty && token.empty()))   
     24         {                
     25             result.push_back(token);     
     26         }            
     27         if ((start = end) != string::npos) start += skip;        
     28     }       
     29 
     30     return result;
     31 }
     32 
     33 void SplitProperty(vector<string> property,string* name,string *value)
     34 {    
     35     vector<string>::iterator it=property.begin();    
     36     if(it!= property.end())    
     37     {       
     38         name->clear();       
     39         name->append(*it);    
     40     }    
     41     it++;   
     42     if(it!= property.end())   
     43     {       
     44         value->clear();       
     45         value->append(*it);   
     46     }
     47 }
     48 
     49 
     50 CHttpDownLoad::CHttpDownLoad(void)
     51 {
     52     m_filesize = 0;
     53     m_hsize = 0;
     54     m_iProgress = 0;
     55     m_pUdateBase = NULL;
     56 }
     57 
     58 
     59 CHttpDownLoad::~CHttpDownLoad(void)
     60 {
     61 }
     62 
     63 void DownloadFile(const char* host,
     64     const char* file,
     65     const char * savefile,
     66     float size,int hsize,
     67     int& progress,
     68     updateBase* handler
     69     )
     70 {
     71     struct sockaddr_in servaddr;
     72     struct hostent *hp;
     73     string info;
     74     int sock_id;
     75     //char message[18000] = {0};
     76     char *message = new char[18000];
     77     memset(message,0,18000);
     78     //char messagetop[18000]={0}; 
     79     char *messagetop = new char[18000];
     80     memset(messagetop,0,18000);
     81     int msglen; 
     82     float readcount=0;
     83     string request;
     84     request.append("GET ");  
     85     request.append(file);   
     86     request.append(" HTTP/1.1
    ");    
     87     request.append("Host:");   
     88     request.append(host);   
     89     request.append("
    
    ");      
     90     if((sock_id = socket(AF_INET, SOCK_STREAM, 0)) == -1) 
     91     {        
     92         return;   
     93     }    
     94     memset(&servaddr,0,sizeof(servaddr));     
     95     if((hp = gethostbyname(host)) == NULL) 
     96     {        
     97         return;    
     98     } 
     99     memcpy((char *)&servaddr.sin_addr.s_addr, (char *)hp->h_addr, hp->h_length);     
    100     servaddr.sin_port = htons(80);   
    101     servaddr.sin_family = AF_INET;     
    102     if(connect(sock_id, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0)
    103     {        
    104         return; 
    105     }    
    106     write(sock_id,request.c_str(),request.length());   
    107     ofstream outfile (savefile,ofstream::binary);
    108     do{        
    109         msglen = read(sock_id,message,18000);
    110         if(msglen==0)
    111         {
    112             break;
    113         }
    114 
    115         if(readcount==0)         
    116         {           
    117             int tempindex=0; 
    118             //for(int i =hsize - 1;i<msglen;i++)
    119             for(int i =hsize;i<msglen;i++)
    120             {               
    121                 messagetop[tempindex]= message[i];                
    122                 tempindex=tempindex+1;            
    123             }
    124             outfile.write (messagetop,tempindex);         
    125         }        
    126         else        
    127         {       
    128             outfile.write (message,msglen);         
    129         }        
    130         readcount=readcount+msglen;        
    131         progress = readcount/size*100;
    132     }while(readcount<=(size+ hsize));    
    133     outfile.close();    
    134     close(sock_id);
    135 
    136     if (message != NULL)
    137     {
    138         delete[] message;
    139         message = NULL;
    140     }
    141     if (messagetop != NULL)
    142     {
    143         delete[] messagetop;
    144         messagetop = NULL;
    145     }
    146 
    147     handler->CallupdateBaseFinsh();//回调下载结束
    148     
    149 }
    150 
    151 void* UpdateWorCoping(void* data)
    152 {
    153     CHttpDownLoad *pGhttpFile = (CHttpDownLoad*)data;
    154     DownloadFile(pGhttpFile->m_strIP.c_str(),
    155         pGhttpFile->m_strFileName.c_str(),
    156         pGhttpFile->m_strLocFile.c_str(),
    157         pGhttpFile->m_filesize,
    158         pGhttpFile->m_hsize,
    159         pGhttpFile->m_iProgress,
    160         (updateBase*)pGhttpFile->m_pUdateBase
    161         );
    162 
    163     return ((void*)0);
    164 }
    165 
    166 int CHttpDownLoad::GetFileSize(const char* host,const char* file,string* error,int& headersize)
    167 {
    168     int size=-1;    
    169     struct sockaddr_in servaddr;    
    170     struct hostent *hp;    
    171     string splitline="
    ";    
    172     string PName;    
    173     string PValue;    
    174     string splittagbalue=":";    
    175     string info;    
    176     vector<string> properties;    
    177     vector<string> property;    
    178     int sock_id;  
    179     //char message[1024*1024] = {0};
    180     char *message = new char[1024*1024];
    181     memset(message,0,1024*1024);
    182     int msglen;    
    183     string request;    
    184     request.append("HEAD ");    
    185     request.append(file);    
    186     request.append(" HTTP/1.1
    ");    
    187     request.append("Host:");    
    188     request.append(host);    
    189     request.append("
    
    ");
    190     if((sock_id = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    191     {    
    192         error->append("Couldn't get a socket!");        
    193         return size;    
    194     }
    195     memset(&servaddr,0,sizeof(servaddr)); 
    196 
    197     if((hp = gethostbyname(host)) == NULL) 
    198     {        
    199         error->append("Couldn't access network.");        
    200         error->append(host);        
    201         return size;    
    202     }   
    203     memcpy((char *)&servaddr.sin_addr.s_addr, (char *)hp->h_addr, hp->h_length);      
    204     servaddr.sin_port = htons(80);    
    205     servaddr.sin_family = AF_INET;     
    206     if(connect(sock_id, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) 
    207     {        
    208         error->append("Couldn't connect!");        
    209         return size;    
    210     }    
    211     write(sock_id,request.c_str(),request.length());  
    212     msglen = read(sock_id,message,1024*1024);    
    213     headersize= msglen;    
    214     info.append(message,0,msglen);    
    215     close(sock_id);    
    216     properties =Split(info,splitline,true);    
    217     vector<string>::iterator it;    
    218     for (it=properties.begin(); it<properties.end(); it++)    
    219     {       
    220         property= Split(*it,splittagbalue,true);       
    221         SplitProperty(property,&PName,&PValue);       
    222         if(PName=="Content-Length")        
    223         {           
    224             size =atoi(PValue.c_str());            
    225             break;       
    226         }    
    227     }    
    228     if(size==-1)    
    229     {        
    230         error->append("Resource Not Found!");   
    231     }  
    232 
    233     if (message!=NULL)
    234     {
    235         delete[] message;
    236         message = NULL;
    237     }
    238     return size;
    239 
    240 }
    241 
    242 
    243 //给出的这样一个完整的url :"http://10.10.41.112/ressdir/test/111111111.lst"
    244 //对应下面几个参数为:(注意格式)
    245 //str1 = "10.10.41.112";
    246 //str2 = "//ressdir//test//111111111.lst";
    247 //str3 = "/mnt/sdcard/test/111111111.lst";
    248 
    249 void CHttpDownLoad::DownLoad(string str1,string str2,string str3,void *handler)
    250 {
    251     if (str1.empty()||str2.empty()||str3.empty()||handler == NULL)
    252     {
    253         LOGI("0___DownLoad is error!!!");
    254         return;
    255     }
    256     
    257     m_strIP = str1;
    258     m_strFileName= str2;
    259     m_strLocFile = str3;
    260     m_pUdateBase = handler;
    261 
    262     string error;   
    263     m_filesize = GetFileSize(str1.c_str(),str2.c_str(),&error,m_hsize);
    264     if (m_filesize<=0)
    265     {
    266         LOGI("1_____DownLoad is error!!!");
    267         return;
    268     }
    269 
    270     pthread_t thread_id;
    271     pthread_attr_t attr;
    272     pthread_attr_init(&attr);
    273     pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
    274     pthread_create(&thread_id,&attr,UpdateWorCoping,this);
    275 
    276     m_thread_id = thread_id;
    277     pthread_attr_destroy(&attr);
    278 }
    279 
    280 int    CHttpDownLoad::GetDownState()
    281 {
    282     return m_iProgress;//用于下载进度
    283 }

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

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

    理进行http下载。

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

  • 相关阅读:
    Appdelegate 跳转其他页面 获取当前屏幕显示的viewcontroller 获取当前屏幕中present出来的viewcontroller 获取当前导航控制器
    React-Native 环境部署
    关于GCD的那些事
    二,Runtime进行动态添加方法
    一, Runtime 交换方法
    Runtime 概念
    Mac Office安装及破解
    iOS 规范之宏
    规范之UITableViewCell
    Linux 命令
  • 原文地址:https://www.cnblogs.com/wainiwann/p/3214835.html
Copyright © 2011-2022 走看看