使用libcurl实现的上传器

头文件

/**********************************************************************
* Copyright (C) 2014 -  - All Rights Reserved
*
* 文件名称:        Uploader_LibCurl.h
* 摘    要:        上传器 - LibCurl实现
*     
* 作    者:        yanglinbo,
* 修    改:        查看文件最下方.

***********************************************************************/

#ifndef __Uploader_LibCurl_H__
#define __Uploader_LibCurl_H__


#include <curl/curl.h>
#include <fstream>
#include <string>


class CUploader
{
public:
    CUploader(void);
    virtual ~CUploader(void);

public:
    /// 线程入口函数
    virtual bool run();

    /// 启动上传
    virtual bool start(const std::string& strUrl, const std::string& strLocalFile);

    /// 停止上传
    virtual bool stop();

    /// 是否运行状态
    bool isRunning() const;

protected:
    /// 读取回调
    static size_t handleRead(void *buffer, size_t size, size_t nmemb, void *userp);

    /// 进度回调
    static size_t handleProgress(void *buffer, double dltotal, double dlnow, double ultotal, double ulnow);

protected:
    /// 读取回调
    size_t onUpload(void *buffer, size_t size, size_t nmemb);

    /// 进度回调
    size_t onProgress(const double& ultotal, const double& ulnow);

    /// 上传回调
    void onUpload();

protected:
    /// 设置libcurl选项
    bool setOption();

    /// 清除数据
    void clear();

protected:
    CURL*            m_pCurl;                ///< libcurl句柄
    FILE*            m_pFile;                ///< 文件指针

    bool            m_bRunning;                ///< 运行标志

    std::string        m_strRemoteUrl;            ///< 远程链接
    std::string        m_strLocalFilePath;        ///< 本地文件路径

    size_t            m_nLocalFileSize;        ///< 本地文件大小
};


#endif

实现文件

/**********************************************************************
* Copyright (C) 2014 -  - All Rights Reserved
*
* 文件名称:        Uploader_LibCurl.cpp
* 摘    要:        上传器 - LibCurl实现
*     
* 作    者:        yanglinbo,
* 修    改:        查看文件最下方.

***********************************************************************/

#include "StdAfx.h"
#include "Uploader.h"
#include <sys/stat.h>
#include <fcntl.h>


CUploader::CUploader(void)
: m_pCurl(NULL)
, m_pFile(NULL)
, m_bRunning(false)
, m_nLocalFileSize(0)
{
}

CUploader::~CUploader(void)
{
    stop();
}

bool CUploader::run()
{
    onUpload();
    return true;
}

bool CUploader::isRunning() const
{
    return m_bRunning;
}

void CUploader::clear()
{
    if (m_pFile)
    {
        fclose(m_pFile);
        m_pFile = NULL;
    }

    if (m_pCurl)
    {
        curl_easy_cleanup(m_pCurl);
        m_pCurl = NULL;
        curl_global_cleanup();
    }

    m_strRemoteUrl.clear();
    m_strLocalFilePath.clear();

    m_nLocalFileSize = 0;
}

bool CUploader::setOption()
{
    // 远程URL,支持 http, https, ftp
    curl_easy_setopt(m_pCurl, CURLOPT_URL, m_strRemoteUrl.c_str());

    curl_easy_setopt(m_pCurl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)m_nLocalFileSize);

    // 设置User-Agent
    std::string useragent = _T("Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20100101 Firefox/13.0.1");
    curl_easy_setopt(m_pCurl, CURLOPT_USERAGENT, useragent.c_str());

    // 设置重定向的最大次数
    curl_easy_setopt(m_pCurl, CURLOPT_MAXREDIRS, 5);

    // 设置301、302跳转跟随location
    curl_easy_setopt(m_pCurl, CURLOPT_FOLLOWLOCATION, 1);

    curl_easy_setopt(m_pCurl, CURLOPT_UPLOAD, TRUE);

    curl_easy_setopt(m_pCurl, CURLOPT_NOSIGNAL, 1L);
    curl_easy_setopt(m_pCurl, CURLOPT_POST, TRUE);
    curl_easy_setopt(m_pCurl, CURLOPT_FORBID_REUSE, TRUE);

    // 上传内容回调函数
    curl_easy_setopt(m_pCurl, CURLOPT_READFUNCTION, handleRead);
    curl_easy_setopt(m_pCurl, CURLOPT_READDATA, this);

    // 进度回调函数
    curl_easy_setopt(m_pCurl, CURLOPT_NOPROGRESS, 0);
    curl_easy_setopt(m_pCurl, CURLOPT_PROGRESSDATA, this);
    curl_easy_setopt(m_pCurl, CURLOPT_PROGRESSFUNCTION, handleProgress);

    // 跳过服务器SSL验证,不使用CA证书
    curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYPEER, 0L);

    // 验证服务器端发送的证书,默认是 2(高),1(中),0(禁用)
    curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYHOST, 0L);

    return true;
}

bool CUploader::start(const std::string& strUrl, const std::string& strLocalFile)
{
    if (strUrl.empty()) return false;

    if (m_bRunning == true) return true;

    clear();

    m_strRemoteUrl    = strUrl;
    m_strLocalFilePath    = strLocalFile;

    // 打开文件
    m_pFile = fopen(m_strLocalFilePath.c_str(), "rb");
    if (m_pFile == NULL)
    {
        return false;
    }

    // 获取文件大小
    struct stat file_info;
    if (fstat(fileno(m_pFile), &file_info) != 0) 
    {
        return false;
    }
    m_nLocalFileSize = file_info.st_size;

    // 初始化libcurl
    m_pCurl = curl_easy_init();
    if (m_pCurl == NULL)
    {
        return false;
    }

    // 设置libcurl的选项
    setOption();

    m_bRunning = true;

    return true;
}

bool CUploader::stop()
{
    clear();

    m_bRunning = false;

    return true;
}

size_t CUploader::handleRead( void *buffer, size_t size, size_t nmemb, void *userp )
{
    CUploader* pDownloader = (CUploader*) userp;
    if (pDownloader)
    {
        return pDownloader->onUpload(buffer, size, nmemb);
    }
    return 0;
}

size_t CUploader::handleProgress( void *buffer, double dltotal, double dlnow, double ultotal, double ulnow )
{
    CUploader* pDownloader = (CUploader*) buffer;
    if (pDownloader)
    {
        pDownloader->onProgress(ultotal, ulnow);
    }
    return 0;
}

size_t CUploader::onProgress( const double& ultotal, const double& ulnow )
{
    TRACE("%.2f / %.2f (%.2g %%)\n", ulnow, ultotal, ulnow*100.0/ultotal);
    return 0;
}

size_t CUploader::onUpload( void *buffer, size_t size, size_t nmemb )
{
    size_t return_size = fread(buffer, size, nmemb, m_pFile);
    return return_size;
}

void CUploader::onUpload()
{
    // 执行上传
    CURLcode return_code = CURLE_OK;
    return_code = curl_easy_perform(m_pCurl);

    // 关闭文件
    if (m_pFile)
    {
        fclose(m_pFile);
        m_pFile = NULL;
    }

    // 上传失败
    if (return_code != CURLE_OK)
    {
        return;
    }

    // 获取状态码
    int response_code = 0;
    curl_easy_getinfo(m_pCurl, CURLINFO_RESPONSE_CODE, &response_code);
}

示例代码:

CUploader uploader
uploader.start("ftp://upload:upload@127.0.0.1/hello.exe", "C:\\fly.exe");
uploader.run();

时间: 2017-10-09

使用libcurl实现的上传器的相关文章

服务器-libcurl Post 方法上传文件求助!

问题描述 libcurl Post 方法上传文件求助! Hi 我在我的虚拟机上编译好了libcurl库,然后参照列程写了个简单的http post上传文件. 在构建form表单的时候,如果把参数设置为CURLFORM_FILE 并输入对应的文件名,可以再服务器(HFS)指定的文件路径下看到我上传的文件. 但我要使用libcurl的平台没有文件系统,所以就打算用CURLFORM_BUFFER参数来设置数据区.结果这个能够上传,可是不能再文件路径下看到这个文件. HFS的上传权限打开了的. 对比两种

Java Socket+mysql实现简易文件上传器的代码_java

最近跟着某网站学习了一个小项目,因为白天有课,所以都是晚上写的,今天把它完成了. 项目主要是实现一个文件上传器,通过客户端的登陆,把本地文件上传到服务器的数据库(本地的). 首先建两个表如下: 一个文件信息表 CREATE TABLE `fileinfo` ( `Fname` char(50) NOT NULL, `FInfo` blob NOT NULL, `FId` int(10) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`FId`) ) ENGINE=I

使用libcurl进行文件上传

上篇博文讲到了如何使用multicurl来进行http并发访问,今天继续有关curl的主题,来八一八如何使用curl来上传文件,在介绍具体方法之前了解下目前http文件上传的基本实现.     rfc1867描述了如何使用http协议来上传客户端文件,目前基本上所有的浏览器和web服务器都支持http文件上传,它的使用也十分的简单,具体的来说就是在页面上创建一个form表单,表单的enctype属性为multipart/form-data,action为接收上传文件的cgi url,请求方式为p

CURL 和LIBCURL C++代码 上传本地文件,好不容易碰到了这种折腾我几天的代码

解决了什么问题:curl在使用各种方式上传文件到服务器.一般的文件上传是通过html表单进行的,通过CURL可以不经过浏览器,直接在服务器端模拟进行表单提交,完成POST数据.文件上传等功能. 服务器端PHP代码: <?phpif ((($_FILES["file"]["type"] == "image/gif") || ($_FILES["file"]["type"] == "image/

libCurl的文件上传

最近在需要使用curl的上传功能,使用libCurl来实现.因此,先使用curl命令操作,然后再使用libCurl实现. 基于Http协议的文件上传的标准方法是: 基于POST Form的文件上传  RFC1867. 这个方法使用非常广泛,这个RFC规定了FORM上传文件的标准方法,如下介绍了基于libcurl来开发upload功能. 开发实现过程                       1. 使用curl 命令行执行代码,  2. 跟踪分析 curl的request和response, 3

咪咕音乐播放器如何上传/下载列表

  咪咕音乐播放器上传/下载列表的方法如下: 用鼠标右键打开控制菜单选择"上传/下载列表",可以把播放列表和收藏列表中的歌曲上传到服务器中,客户更换登录地点下载列表后,将服务器中保存的列表下载到咪咕音乐播放器中.特别适合网吧客户.

修正Strut2 自带上传拦截器功能

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://dba10g.blog.51cto.com/764602/857866 Struts2字典的FileUploadInterceptor 拦截器 主要帮助获取上传文件的ContentType.fileName.文件对象.如果开发人员在开发过程中使用.则需要设置set/get方法: 比如 setXXXContentType()  getXXXFileName()  getXXXCon

link环境下,使用codefirst制作的《网盘软件》下载器,如何右键上传?

问题描述 link环境下,使用codefirst制作的<网盘软件>下载器,如何右键上传? link环境下,使用codefirst制作的<网盘软件>下载器,如何右键上传? 解决方案 http://wenku.it168.com/d_001129464.shtml 解决方案二: 在SHELL的上下文菜单上增加一个上传的项

04springMVC结构,mvc模式,spring-mvc流程,spring-mvc的第一个例子,三种handlerMapping,几种控制器,springmvc基于注解的开发,文件上传,拦截器,s

 1. Spring-mvc介绍 1.1市面上流行的框架 Struts2(比较多) Springmvc(比较多而且属于上升的趋势) Struts1(即将被淘汰) 其他 1.2  spring-mvc结构  DispatcherServlet:中央控制器,把请求给转发到具体的控制类 Controller:具体处理请求的控制器(配置文件方式需要配置,注解方式不用配置) handlerMapping:映射处理器,负责映射中央处理器转发给controller时的映射策略 ModelAndView:服