有一个控制下载的管理类吧,调用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\n"); 87 request.append("Host:"); 88 request.append(host); 89 request.append("\r\n\r\n"); 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="\r\n"; 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\n"); 187 request.append("Host:"); 188 request.append(host); 189 request.append("\r\n\r\n"); 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() 获取下载的进度以用于其它目的。