1. 程式人生 > >libcurl編譯使用,實現ftp功能

libcurl編譯使用,實現ftp功能

Libcurl實現ftp的下載,上傳功能。版本為curl-7.63.0

 

1、編譯vs2015

參考資料:https://blog.csdn.net/yaojingkao/article/details/53044361

 

2、libcurl傳輸進度參考:

https://blog.csdn.net/u012234115/article/details/83869486

3、libcurl使用方法參考:

https://www.cnblogs.com/mengfanrong/p/4581068.html

4、在搜尋資料的時候,應該注意libcurl版本的問題,不同的版本,用法可能不同。

 

官網下載:

 

 

 

解壓到本地,使用vs2015開啟解決方案:

 

 

 

 

 

選擇libcurl,DLL Release,32位,進行編譯

 

 

 

 

 

編譯完成後,生成的庫檔案libcurl.dll  和 libcurl.lib 在下面的目錄中

 

 

 

 

2、使用:vs2015新建測試工程:

 

 

 

 

需要libcurl的標頭檔案跟動態庫。

libcurl標頭檔案路徑:

 

 

 

 

 

將libcurl標頭檔案跟庫檔案,放到ftptest.sln解決方案下面

在ftptest.sln同級目錄下,新建include和lib目錄

 

 

將libcurl的標頭檔案拷貝到include目錄下

 

 

 

將libcurl的庫拷貝到lib目錄下目錄下

 

 

 

 

 

 

 

 

 

 

 

將libcurl標頭檔案加入到工程配置中:

 

 

 

將libcurl庫加入到工程配置中:

 

在工程中連線libcurl庫:

 

 

 

 

 

對libcurl進行c++封裝,測試,c++使用Qt

標頭檔案:

#ifndef FTPLIBCURL_H

#define FTPLIBCURL_H

 

#include "curl/curl.h"

#include "curl/easy.h"

#include <QObject>

 

class FtpLibCurl;

struct CustomProgress

{

    curl_off_t lastruntime; /* type depends on version, see above */

    CURL *curl;

    FtpLibCurl* p;

};

 

class FtpLibCurl : public QObject

{

    Q_OBJECT

 

public:

    FtpLibCurl(QObject *parent);

    ~FtpLibCurl();

 

public:

    void getProg(qulonglong);

    void setFile(const QString&);

 

public slots:

    void process();

    void downFile();

 

signals:

    void finished();

    void error(QString err);

    void ftp_prog(QString);

 

public:

    struct CustomProgress prog;

 

private:

    qulonglong m_fileSize;

    QString m_s_percentage;

    QString m_fileName;

};

 

#endif // FTPLIBCURL_H

 

 

 

 

Cpp檔案:

#include "FtpLibCurl.h"

 

//#define F_LOCAL_FILE     "F:/1.jpg"

//#define F_REMOTE_URL     "ftp://192.168.16.166:21//home/msj/1.jpg"

 

 

 

size_t f_read_callback(void *ptr, size_t size, size_t nmemb, void *stream) //回撥函式

{

    curl_off_t nread;

    size_t retcode = fread(ptr, size, nmemb, (FILE*)(stream));

    nread = (curl_off_t)retcode;

    return retcode;

}

 

// work for both download and upload

int progressCallback(void *p,

    curl_off_t dltotal,

    curl_off_t dlnow,

    curl_off_t ultotal,

    curl_off_t ulnow)

{

    struct CustomProgress *progress = (struct CustomProgress *)p;

    CURL *curl = progress->curl;

    curl_off_t curtime = 0;

 

    curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME_T, &curtime);

 

    /* under certain circumstances it may be desirable for certain functionality

    to only run every N seconds, in order to do this the transaction time can

    be used */

    if ((curtime - progress->lastruntime) >= 3000000)

    {

        progress->lastruntime = curtime;

        //printf("TOTAL TIME: %f \n", curtime);

    }

 

    // do something to display the progress

    //printf("UP: %ld bytes of %ld bytes, DOWN: %ld bytes of %ld bytes \n", ulnow, ultotal, dlnow, dltotal);

    if (ultotal)

    {

        //printf("UP progress: %0.2f\n", float(ulnow / ultotal));

        progress->p->getProg(ulnow);

    }

    if (dltotal)

    {

        //("DOWN progress: %0.2f\n", float(dlnow / dltotal));

    }

       

 

 

    return 0;

}

 

FtpLibCurl::FtpLibCurl(QObject *parent)

    : QObject(parent)

{

    prog = {0};

 

    m_s_percentage = QString("0%");

    m_fileName.clear();

}

 

FtpLibCurl::~FtpLibCurl()

{

 

}

 

 

 

void FtpLibCurl::process()

{

    CURL *pCurlhandle;

    CURLcode res;

    FILE *hd_src;

    struct stat file_info;

    curl_off_t fsize;

 

    QByteArray ba = m_fileName.toLocal8Bit();

    const char *c_str = ba.constData();

 

 

    /*1. 獲取待上傳檔案的大小 */

    if (stat(c_str, &file_info)) {

        printf("Couldnt open '%s': %s\n", c_str, strerror(errno));

        emit error(QString("local file not exist"));

        return;

    }

    fsize = (curl_off_t)file_info.st_size;

    m_fileSize = fsize;

 

    /*2. 獲取待上傳檔案的描寫敘述符 */

    hd_src = fopen(c_str, "rb");

 

    /*3. 初始化全部可能的呼叫*/

    curl_global_init(CURL_GLOBAL_ALL);

 

    /*4. 建立一個curlhandle*/

    pCurlhandle = curl_easy_init();

 

    if (pCurlhandle)

    {

        curl_easy_setopt(pCurlhandle, CURLOPT_USERPWD, "msj:msj");

 

        /*5.設定一個回撥函式 */

        curl_easy_setopt(pCurlhandle, CURLOPT_READFUNCTION, f_read_callback);

 

        /*6.使能上傳標誌位 */

        curl_easy_setopt(pCurlhandle, CURLOPT_UPLOAD, 1L);

 

        /*7.指定ftpserver的url */

        QStringList path_list = m_fileName.split('/');

        QString tmp_url = "ftp://192.168.16.166:21//home/xx/" + path_list.last();

        QByteArray url_ba = tmp_url.toLocal8Bit();

        const char *url_str = url_ba.constData();

 

        curl_easy_setopt(pCurlhandle, CURLOPT_URL, url_str);

 

        /*8.指定須要上傳的檔案 */

        curl_easy_setopt(pCurlhandle, CURLOPT_READDATA, hd_src);

 

        /*9.設定待上傳檔案的大小,這個大小是上面獲取到的注意:當引數

        為CURLOPT_INFILESIZE_LARGE的時候。size型別應該是curl_off_t的,

        當引數為CURLOPT_INFILESIZE的時候size應該是long型別的*/

        curl_easy_setopt(pCurlhandle, CURLOPT_INFILESIZE_LARGE,

            (curl_off_t)fsize);

 

        // set upload progress

        curl_easy_setopt(pCurlhandle, CURLOPT_XFERINFOFUNCTION, progressCallback);

        curl_easy_setopt(pCurlhandle, CURLOPT_XFERINFODATA, &prog);

        prog.p = this;

        curl_easy_setopt(pCurlhandle, CURLOPT_NOPROGRESS, 0);

 

        /*10. 開始執行我們上述設定的方法*/

        res = curl_easy_perform(pCurlhandle);

        /*11. 檢查是否執行成功 */

        if (res != CURLE_OK)

        {

            fprintf(stderr, "curl_easy_perform() failed: %s\n",

                curl_easy_strerror(res));

 

            emit error(QString(curl_easy_strerror(res)));

        }

 

        /*12. 關閉pCurlhandle*/

        curl_easy_cleanup(pCurlhandle);

    }

    fclose(hd_src); /* close the local file */

                    /*13. 清除全部可能的呼叫*/

    curl_global_cleanup();

 

    emit finished();

}

 

void FtpLibCurl::getProg(qulonglong v)

{

    int int_percentage = (v / m_fileSize)*100;

    QString tmp_percentage = QString::number(int_percentage) + "%";

    if (m_s_percentage!= tmp_percentage)

    {

        m_s_percentage = tmp_percentage;

        emit ftp_prog(tmp_percentage);

    }

   

}

 

void FtpLibCurl::downFile()

{

 

}

 

void FtpLibCurl::setFile(const QString& s)

{

    m_fileName = s;

}

 

 

 

 

 

 

 

 

 

測試程式碼:

    QThread *thread = new QThread();

    FtpLibCurl *worker = new FtpLibCurl(nullptr);

 

    worker->setFile(QString("F:/1.jpg"));

    worker->moveToThread(thread);

 

    // 錯誤處理

    connect(worker, SIGNAL(error(QString)), this, SLOT(errorString(QString)));

 

    // 處理資料

    connect(thread, SIGNAL(started()), worker, SLOT(process()));

 

    // 退出、刪除

    connect(worker, SIGNAL(error(QString)), this, SLOT(ftp_error(QString)));

    connect(worker, SIGNAL(finished()), thread, SLOT(quit()));

    connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));

    connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));

 

    // 啟動執行緒

    thread->start();