结合Poco库的一个httpdown方法
poco库很丰富,
这里列举了生成 guide,httpdownload 的2个方法。
下载的时候,顺便打印了当前下载进度。
#include <sstream> #include <iomanip> #include <istream> #include <ostream> #include <iostream> #include <fstream> // ofstream #include <Poco/Path.h> #include <openssl/bio.h> #include <openssl/evp.h> #include <Poco/File.h> #include <Poco/DirectoryIterator.h> #include <Poco/Net/HTTPClientSession.h> #include <Poco/Net/HTTPRequest.h> #include <Poco/Net/HTTPResponse.h> #include <Poco/URI.h> #include <Poco/Path.h> #include <Poco/UUIDGenerator.h> std::string genUUID() { Poco::UUIDGenerator generator; Poco::UUID uuid = generator.createRandom(); std::string uuidStr = uuid.toString(); return uuidStr; } // 显示进度条的简单函数 void showProgress(size_t received, size_t total) { if (total == 0) return; // 避免除以零错误 int barWidth = 70; double progress = (double)received / total; int pos = barWidth * progress; std::cout << "["; for (int i = 0; i < barWidth; ++i) { if (i < pos) std::cout << "="; else if (i == pos) std::cout << ">"; else std::cout << " "; } std::cout << "] " << int(progress * 100.0) << " %\r"; std::cout.flush(); } int httpDownload(const std::string &url, const std::string& dirPath) { try { printf("url:%s\r\n\r\n", url.c_str()); printf("dirPath:%s\r\n\r\n", dirPath.c_str()); Poco::URI uri(url); std::cout << "uri.getPath: " << uri.getPath() << ", getHost: " << uri.getHost() << ", getPort: " << uri.getPort() << std::endl; Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, uri.getPathAndQuery(), Poco::Net::HTTPMessage::HTTP_1_1); // 添加请求头以获取内容长度(如果服务器支持) request.add("Range", "bytes=0-"); Poco::Net::HTTPClientSession session(uri.getHost(), uri.getPort()); std::ostream& requestStream = session.sendRequest(request); requestStream.flush(); Poco::Net::HTTPResponse response; std::istream& responseStream = session.receiveResponse(response); if (response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK || response.getStatus() == Poco::Net::HTTPResponse::HTTP_PARTIAL_CONTENT) { long contentLength = response.getContentLength(); std::string filename = Poco::Path(uri.getPath()).getFileName(); Poco::Path fullPath(dirPath, filename); std::cout << "fullpath: " << fullPath.toString() << ", contentLength:"<<contentLength << std::endl; std::ofstream outputFile(fullPath.toString(), std::ios::binary); if (!outputFile) { return 1; } char buffer[8192]={0}; size_t totalReceived = 0; while (responseStream && !outputFile.fail()) { responseStream.read(buffer, sizeof(buffer)); std::streamsize bytesRead = responseStream.gcount(); if (bytesRead > 0) { outputFile.write(buffer, bytesRead); totalReceived += bytesRead; showProgress(totalReceived, contentLength); } } if (outputFile.fail()) { return 1; } std::cout << std::endl; // 换行以结束进度条显示 } else { printf("HTTP request failed with status: %d\r\n", response.getStatus()); return 1; } responseStream.clear(); session.reset(); } catch (const Poco::Exception& ex) { printf("Poco exception: %s\r\n", ex.displayText().c_str()); return 1; } catch (const std::exception& ex) { printf("Standard exception: %s\r\n", ex.what()); return 1; } catch (...) { printf("Unknown exception\r\n"); return 1; } return 0; } std::string getFileNameFromURL(const std::string &url) { Poco::URI uri(url); std::string path = uri.getPath(); Poco::Path pocoPath(path); return pocoPath.getFileName(); } void test(){ std::string strDownloadUrl = "http://xz.winwin7xz.com/Small/JAVAkaifa.zip"; std::cout<<"filename:"<<getFileNameFromURL(strDownloadUrl)<<std::endl; std::cout<<"====================start download ===================="<<std::endl; int iRet = httpDownload(strDownloadUrl, "./Downloads"); std::cout<<" download finished, iRet:"<<iRet<<std::endl<<std::endl; } void test2(){ for(int i=0; i<20; ++i){ std::cout<<"["<<i<<"]: "<< genUUID()<<std::endl; } std::cout<<std::endl<<std::endl; } int main(){ test2(); test(); return 0; }
程序运行情况:
./bin/httpdownload [0]: 197c0aaf-c253-477a-a739-0d2e7f3bcf85 [1]: d6ee2b5e-b3a7-4069-bb3c-ca2e2566fbcc [2]: 83391c46-8c91-4819-b02f-30ad2bd91f26 [3]: e4dc88c5-4a75-466d-aa55-5315a7b74e9c [4]: 248e71bf-14b6-494d-9dc2-a5df18653b1a [5]: 86122319-0827-4fb2-83b9-b8c3990d6f29 [6]: 55ad38af-d95c-4317-898c-82abe6ee036e [7]: 7facb35a-525d-4f81-8e50-28f0bd742c57 [8]: 78bf2d0b-d119-43df-ab14-176cf85b3ae4 [9]: b8721680-d407-40e5-aec3-1b43c3c7c44b [10]: 2620278b-5b4e-4bc4-8b85-ffd6e1dec86f [11]: d9260f57-18ec-4661-9afe-4d637dbdb0d8 [12]: c0e198c3-daa4-40e3-8b0c-962119f7d00f [13]: 3e65a64b-c8bc-4011-bfb1-d371d7abcf6d [14]: 67b8d056-58e3-4df3-a6a8-eeb6e2cb7762 [15]: f2e750f5-8aef-45f4-a5b1-fb8e12fb8b69 [16]: 9fdea346-105f-48f4-a4c4-538e599bd777 [17]: 6ed7e2cf-92e2-4084-adf9-0b552b1f602f [18]: 45245547-a7d3-44e4-9981-e96560df0326 [19]: 2fa938df-eafa-4608-97f2-25983b7b8899 filename:JAVAkaifa.zip ====================start download ==================== url:http://xz.winwin7xz.com/Small/JAVAkaifa.zip dirPath:./Downloads uri.getPath: /Small/JAVAkaifa.zip, getHost: xz.winwin7xz.com, getPort: 80 fullpath: Downloads/JAVAkaifa.zip, contentLength:146090253 [================================================================> ] 92 %