结合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 %

 

posted @ 2024-11-08 17:05  He_LiangLiang  阅读(10)  评论(0编辑  收藏  举报