#include <iostream>
#define Main main
#include <string>
#include <assert.h>
#include <curl/curl.h>
#include <curl/easy.h> #pragma comment(lib,"libcurl.lib")
#pragma comment(lib,"ws2_32.lib") using namespace std; class CLibcurlCallback
{
public:
virtual void Progress(void* lpParam, double dTotal, double bLoaded) = ;
}; enum LibcurlFlag
{
Lf_None = ,
Lf_Download,
Lf_Post,
Lf_Get,
}; class CLibcurl
{
public:
CLibcurl(void);
~CLibcurl(void);
/******************************************************************************
*封装类的外部调用接口
*/
bool SetPorts(LONG port); //设置连接端口号
bool SetTimeout(int nSecond); //设置执行超时(秒)
bool SetConnectTimeout(int nSecond); //设置连接超时(秒)
bool SetUserAgent(LPCSTR lpAgent); //设置用户代理
bool SetResumeFrom(LONG lPos); //设置断点续传起始位置
bool SetResumeFromLarge(LONGLONG llPos); //设置断点续传起始位置,针对大文件
bool AddHeader(LPCSTR lpKey, LPCSTR lpValue); //添加自定义头
void ClearHeaderList(); //清理HTTP列表头
bool SetCookie(LPCSTR lpCookie); //设置HTTP请求cookie
bool SetCookieFile(LPCSTR lpFilePath); //设置HTTP请求cookie文件
const char* GetError()const; //获取错误详细信息
void SetCallback(CLibcurlCallback* pCallback, void* lpParam); //设置下载进度回调
bool DownloadToFile(LPCSTR lpUrl, LPCSTR lpFile); //下载文件到磁盘
bool Post(LPCSTR lpUrl, LPCSTR lpData); //Post 字符串数据
bool Post(LPCSTR lpUrl, unsigned char* lpData, unsigned int nSize); //Post 字符串或者二进制数据
bool Get(LPCSTR lpUrl); //Get 请求
const string& GetRespons()const; //获取Post/Get请求返回数据
const char* GetResponsPtr()const; //获取Post/Get请求返回数据 protected:
static size_t WriteCallback(void* pBuffer, size_t nSize, size_t nMemByte, void* pParam);
static size_t HeaderCallback(void* pBuffer, size_t nSize, size_t nMemByte, void* pParam);
static int ProgressCallback(void *pParam, double dltotal, double dlnow, double ultotal, double ulnow); private:
CURL *m_pCurl;
LONG m_nPort;
HANDLE m_hFile;
CURLcode m_curlCode;
string m_strRespons;
LibcurlFlag m_lfFlag;
curl_slist *m_curlList;
void *m_pCallbackParam;
CLibcurlCallback *m_pCallback;
};
class CLibcurlCallbackEx
: public CLibcurlCallback
{
public:
virtual void Progress(void* lpParam, double dTotal, double dLoaded)
{
if (dTotal == 0.0)
return;
double bPercent = (dLoaded / dTotal) * ;
printf("下载进度:%0.2lf%%\n", bPercent);
} }; class CommonTools
{
public:
CommonTools() {}
~CommonTools() {}
public:
static size_t receive_data(void *contents, size_t size, size_t nmemb, void *stream);
// HTTP 下载文件的回掉函数
static size_t writedata2file(void *ptr, size_t size, size_t nmemb, FILE *stream);
// 文件下载接口
static int download_file(const char* url, const char outfilename[FILENAME_MAX]);
// http get 请求
static CURLcode HttpGet(const std::string & strUrl, std::string & strResponse, int nTimeout);
// htpp post 请求
static CURLcode HttpPost(const std::string & strUrl, std::string szJson, std::string & strResponse, int nTimeout);
}; int Main()
{
//string url("http://t.weather.sojson.com/api/weather/city/101270101");
//string buf;
//CommonTools::HttpGet(url, buf, 300); //FILE *File = NULL;
//fopen_s(&File, "test.json", "wb+");
//if (File)
//{
// fwrite(buf.c_str(), buf.length(), 1, File);
//}
//fclose(File);
//File = NULL; system("pause");
return ;
} CLibcurl::CLibcurl(void)
: m_pCurl(NULL)
, m_nPort()
, m_hFile(INVALID_HANDLE_VALUE)
, m_pCallback(NULL)
, m_pCallbackParam(NULL)
, m_curlCode(CURLE_OK)
, m_lfFlag(Lf_None)
, m_curlList(NULL)
{
m_pCurl = curl_easy_init();
curl_easy_setopt(m_pCurl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(m_pCurl, CURLOPT_WRITEDATA, this);
} CLibcurl::~CLibcurl(void)
{
ClearHeaderList();
curl_easy_cleanup(m_pCurl);
if (m_hFile != INVALID_HANDLE_VALUE)
{
CloseHandle(m_hFile);
}
} bool CLibcurl::SetPorts(LONG port)
{
if (port == m_nPort)
return true;
m_nPort = port;
m_curlCode = curl_easy_setopt(m_pCurl, CURLOPT_PORT, m_nPort);
return CURLE_OK == m_curlCode;
} bool CLibcurl::SetTimeout(int nSecond)
{
if (nSecond < )
return false;
m_curlCode = curl_easy_setopt(m_pCurl, CURLOPT_TIMEOUT, nSecond);
return CURLE_OK == m_curlCode;
} bool CLibcurl::SetConnectTimeout(int nSecond)
{
if (nSecond < )
return false;
m_curlCode = curl_easy_setopt(m_pCurl, CURLOPT_CONNECTTIMEOUT, nSecond);
return CURLE_OK == m_curlCode;
} bool CLibcurl::SetUserAgent(LPCSTR lpAgent)
{
if (NULL == lpAgent)
return false;
int nLen = strlen(lpAgent);
if (nLen == )
return false;
m_curlCode = curl_easy_setopt(m_pCurl, CURLOPT_USERAGENT, lpAgent);
return CURLE_OK == m_curlCode;
} bool CLibcurl::SetResumeFrom(LONG lPos)
{
if (lPos < )
return false;
m_curlCode = curl_easy_setopt(m_pCurl, CURLOPT_RESUME_FROM, lPos);
return CURLE_OK == m_curlCode;
} bool CLibcurl::SetResumeFromLarge(LONGLONG llPos)
{
if (llPos < )
return false;
m_curlCode = curl_easy_setopt(m_pCurl, CURLOPT_RESUME_FROM_LARGE, llPos);
return CURLE_OK == m_curlCode;
} bool CLibcurl::AddHeader(LPCSTR lpKey, LPCSTR lpValue)
{
assert(lpKey != NULL && lpValue != NULL);
int nLen1 = strlen(lpKey), nLen2 = strlen(lpValue);
assert(nLen1 > && nLen2 > );
string strHeader(lpKey);
strHeader.append(": ");
strHeader.append(lpValue);
m_curlList = curl_slist_append(m_curlList, strHeader.c_str());
m_curlCode = curl_easy_setopt(m_pCurl, CURLOPT_HTTPHEADER, m_curlList);
return CURLE_OK == m_curlCode;
} void CLibcurl::ClearHeaderList()
{
if (m_curlList)
{
curl_slist_free_all(m_curlList);
m_curlList = NULL;
}
} bool CLibcurl::SetCookie(LPCSTR lpCookie)
{
assert(lpCookie != NULL);
m_curlCode = curl_easy_setopt(m_pCurl, CURLOPT_COOKIE, lpCookie);
return CURLE_OK == m_curlCode;
} bool CLibcurl::SetCookieFile(LPCSTR lpFilePath)
{
assert(lpFilePath != NULL);
m_curlCode = curl_easy_setopt(m_pCurl, CURLOPT_COOKIEFILE, lpFilePath);
return CURLE_OK == m_curlCode;
} const char* CLibcurl::GetError() const
{
return curl_easy_strerror(m_curlCode);
} void CLibcurl::SetCallback(CLibcurlCallback* pCallback, void* lpParam)
{
m_pCallbackParam = lpParam;
m_pCallback = pCallback;
} bool CLibcurl::DownloadToFile(LPCSTR lpUrl, LPCSTR lpFile)
{
CURLcode code = curl_easy_setopt(m_pCurl, CURLOPT_URL, lpUrl);
DeleteFileA(lpFile);
m_hFile = CreateFileA(lpFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == m_hFile)
{
return FALSE;
}
curl_easy_setopt(m_pCurl, CURLOPT_NOPROGRESS, );
curl_easy_setopt(m_pCurl, CURLOPT_PROGRESSFUNCTION, ProgressCallback);
curl_easy_setopt(m_pCurl, CURLOPT_PROGRESSDATA, this);
m_lfFlag = Lf_Download;
//开始执行请求
m_curlCode = curl_easy_perform(m_pCurl);
return CURLE_OK == m_curlCode;
} bool CLibcurl::Post(LPCSTR lpUrl, LPCSTR lpData)
{
assert(lpData != NULL);
curl_easy_setopt(m_pCurl, CURLOPT_POST, );
curl_easy_setopt(m_pCurl, CURLOPT_POSTFIELDS, lpData);
//curl_easy_setopt(m_pCurl, CURLOPT_POSTFIELDSIZE, lpData);
curl_easy_setopt(m_pCurl, CURLOPT_URL, lpUrl);
m_lfFlag = Lf_Post;
m_strRespons.clear();
m_curlCode = curl_easy_perform(m_pCurl);
return CURLE_OK == m_curlCode;
} bool CLibcurl::Post(LPCSTR lpUrl, unsigned char* lpData, unsigned int nSize)
{
assert(lpData != NULL && nSize > );
curl_easy_setopt(m_pCurl, CURLOPT_POST, );
curl_easy_setopt(m_pCurl, CURLOPT_POSTFIELDS, lpData);
curl_easy_setopt(m_pCurl, CURLOPT_POSTFIELDSIZE, nSize);
curl_easy_setopt(m_pCurl, CURLOPT_URL, lpUrl);
m_lfFlag = Lf_Post;
m_strRespons.clear();
m_curlCode = curl_easy_perform(m_pCurl);
return CURLE_OK == m_curlCode;
} bool CLibcurl::Get(LPCSTR lpUrl)
{
assert(lpUrl != NULL);
curl_easy_setopt(m_pCurl, CURLOPT_HTTPGET, );
curl_easy_setopt(m_pCurl, CURLOPT_URL, lpUrl);
curl_easy_setopt(m_pCurl, CURLOPT_FOLLOWLOCATION, );//支持重定向
curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYHOST, 0L);
m_lfFlag = Lf_Get;
m_strRespons.clear();
m_curlCode = curl_easy_perform(m_pCurl);
return CURLE_OK == m_curlCode;
} const string& CLibcurl::GetRespons() const
{
return m_strRespons;
} const char* CLibcurl::GetResponsPtr() const
{
return m_strRespons.c_str();
} size_t CLibcurl::WriteCallback(void* pBuffer, size_t nSize, size_t nMemByte, void* pParam)
{
//把下载到的数据以追加的方式写入文件(一定要有a,否则前面写入的内容就会被覆盖了)
CLibcurl* pThis = (CLibcurl*)pParam;
DWORD dwWritten = ;
switch (pThis->m_lfFlag)
{
case Lf_Download://下载
{
if (pThis->m_hFile == INVALID_HANDLE_VALUE)
return ;
if (!WriteFile(pThis->m_hFile, pBuffer, nSize*nMemByte, &dwWritten, NULL))
return ;
}
break;
case Lf_Post://Post数据
case Lf_Get://Get数据
{
pThis->m_strRespons.append((const char*)pBuffer, nSize*nMemByte);
dwWritten = nSize * nMemByte;
}
break;
case Lf_None://未定义
break;
}
return dwWritten;
} size_t CLibcurl::HeaderCallback(void* pBuffer, size_t nSize, size_t nMemByte, void* pParam)
{
CLibcurl* pThis = (CLibcurl*)pParam;
return ;
} int CLibcurl::ProgressCallback(void *pParam, double dltotal, double dlnow, double ultotal, double ulnow)
{
CLibcurl* pThis = (CLibcurl*)pParam;
if (pThis->m_pCallback)
{
pThis->m_pCallback->Progress(pThis->m_pCallbackParam, dltotal, dlnow);
}
return ;
} size_t CommonTools::receive_data(void *contents, size_t size, size_t nmemb, void *stream) {
string *str = (string*)stream;
(*str).append((char*)contents, size*nmemb);
return size * nmemb;
} size_t CommonTools::writedata2file(void *ptr, size_t size, size_t nmemb, FILE *stream) {
size_t written = fwrite(ptr, size, nmemb, stream);
return written;
} int CommonTools::download_file(const char* url, const char outfilename[FILENAME_MAX]) {
CURL *curl;
FILE *fp;
CURLcode res;
/* 调用curl_global_init()初始化libcurl */
res = curl_global_init(CURL_GLOBAL_ALL);
if (CURLE_OK != res)
{
printf("init libcurl failed.");
curl_global_cleanup();
return -;
}
/* 调用curl_easy_init()函数得到 easy interface型指针 */
curl = curl_easy_init();
if (curl) {
fp = fopen(outfilename, "wb"); /* 调用curl_easy_setopt()设置传输选项 */
res = curl_easy_setopt(curl, CURLOPT_URL, url);
if (res != CURLE_OK)
{
fclose(fp);
curl_easy_cleanup(curl);
return -;
}
/* 根据curl_easy_setopt()设置的传输选项,实现回调函数以完成用户特定任务 */
res = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CommonTools::writedata2file);
if (res != CURLE_OK) {
fclose(fp);
curl_easy_cleanup(curl);
return -;
}
/* 根据curl_easy_setopt()设置的传输选项,实现回调函数以完成用户特定任务 */
res = curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
if (res != CURLE_OK)
{
fclose(fp);
curl_easy_cleanup(curl);
return -;
} res = curl_easy_perform(curl);
// 调用curl_easy_perform()函数完成传输任务
fclose(fp);
/* Check for errors */
if (res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
curl_easy_cleanup(curl);
return -;
} /* always cleanup */
curl_easy_cleanup(curl);
// 调用curl_easy_cleanup()释放内存 }
curl_global_cleanup();
return ;
} CURLcode CommonTools::HttpGet(const std::string & strUrl, std::string & strResponse, int nTimeout) {
CURLcode res;
CURL* pCURL = curl_easy_init(); if (pCURL == NULL) {
return CURLE_FAILED_INIT;
} curl_easy_setopt(pCURL, CURLOPT_URL, strUrl.c_str());
//curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(pCURL, CURLOPT_NOSIGNAL, 1L);
curl_easy_setopt(pCURL, CURLOPT_TIMEOUT, nTimeout);
curl_easy_setopt(pCURL, CURLOPT_NOPROGRESS, 1L);
curl_easy_setopt(pCURL, CURLOPT_WRITEFUNCTION, CommonTools::receive_data);
curl_easy_setopt(pCURL, CURLOPT_WRITEDATA, (void*)&strResponse);
res = curl_easy_perform(pCURL);
curl_easy_cleanup(pCURL);
return res;
} CURLcode CommonTools::HttpPost(const std::string & strUrl, std::string szJson, std::string & strResponse, int nTimeout) {
CURLcode res;
char szJsonData[];
memset(szJsonData, , sizeof(szJsonData));
strcpy(szJsonData, szJson.c_str());
CURL* pCURL = curl_easy_init();
struct curl_slist* headers = NULL;
if (pCURL == NULL) {
return CURLE_FAILED_INIT;
} CURLcode ret;
ret = curl_easy_setopt(pCURL, CURLOPT_URL, strUrl.c_str());
// std::cout << ret << std::endl; ret = curl_easy_setopt(pCURL, CURLOPT_POST, 1L);
headers = curl_slist_append(headers, "content-type:application/json"); ret = curl_easy_setopt(pCURL, CURLOPT_HTTPHEADER, headers); ret = curl_easy_setopt(pCURL, CURLOPT_POSTFIELDS, szJsonData);
//curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
ret = curl_easy_setopt(pCURL, CURLOPT_TIMEOUT, nTimeout); ret = curl_easy_setopt(pCURL, CURLOPT_WRITEFUNCTION, CommonTools::receive_data); ret = curl_easy_setopt(pCURL, CURLOPT_WRITEDATA, (void*)&strResponse); res = curl_easy_perform(pCURL);
curl_easy_cleanup(pCURL);
return res;
}

curl 一个使用例子的更多相关文章

  1. php中使用curl两个例子

    第一个例子: 调用一个天气预告的接口 $data = 'theCityName=石家庄'; $cUrl = curl_init(); curl_setopt($cUrl, CURLOPT_URL, & ...

  2. SQL Server Reporting Service(SSRS) 第一篇 我的第一个SSRS例子

    很早就知道SQL SERVER自带的报表工具SSRS,但一直没有用过,最近终于需要在工作中一展身手了,于是我特地按照自己的理解做了以下总结: 1. 安装软件结构 SSRS全称SQL Server Re ...

  3. 一个简单例子:贫血模型or领域模型

    转:一个简单例子:贫血模型or领域模型 贫血模型 我们首先用贫血模型来实现.所谓贫血模型就是模型对象之间存在完整的关联(可能存在多余的关联),但是对象除了get和set方外外几乎就没有其它的方法,整个 ...

  4. java连接mysql的一个小例子

    想要用java 连接数据库,需要在classpath中加上jdbc的jar包路径 在eclipse中,Project的properties里面的java build path里面添加引用 连接成功的一 ...

  5. java操作xml的一个小例子

    最近两天公司事比较多,这两天自己主要跟xml打交道,今天更一下用java操作xml的一个小例子. 原来自己操作xml一直用这个包:xstream-1.4.2.jar.然后用注解的方式,很方便,自己只要 ...

  6. MVVM模式的一个小例子

    使用SilverLight.WPF也有很长时间了,但是知道Binding.Command的基本用法,对于原理性的东西,一直没有深究.如果让我自己建一个MVVM模式的项目,感觉还是无从下手,最近写了一个 ...

  7. Lea指令计算地址(用于四则混合运算),附上一个函数调用例子及其反汇编代码,很清楚

    比如你用local在栈上定义了一个局部变量LocalVar,你知道实际的指令是什么么?一般都差不多像下面的样子:     push   ebp     mov   esp,   ebp     sub ...

  8. (转)Java中使用正则表达式的一个简单例子及常用正则分享

    转自:http://www.jb51.net/article/67724.htm 这篇文章主要介绍了Java中使用正则表达式的一个简单例子及常用正则分享,本文用一个验证Email的例子讲解JAVA中如 ...

  9. C语言多线程的一个简单例子

    多线程的一个简单例子: #include <stdio.h> #include <stdlib.h> #include <string.h> #include &l ...

随机推荐

  1. windows IIS FTP 不支持创建多级目录

    昨天因为这个事情搞了好久,因为客户那边使用的是IIS 上的FTP ,想着都差不多试着运行,结果竟然报错,说"错误550 文件不可用" 是在GetResponse()出现的异常,我用 ...

  2. Flask理论基础(一)视图函数和URL反转函数(url_for)

    一.视图函数 1.1 基本用法试图函数是 app.route 或者 bp.route(蓝图)装饰器装饰的函数.该函数实现了对URL路径的转换,也就是路由功能,例如下面代码定义了默认url ‘/’ 和‘ ...

  3. Django项目从新建到运行

    返回主目录:Django框架 内容目录: 一.安装之前 二.Django安装 三.创建项目 四.配置 一.安装之前 安装django之前你需要注意的几个事项: 1.版本问题 建议使用1.11.11左右 ...

  4. 过滤掉map集合中key或value为空的值

    package cn.com.utils; import org.apache.commons.lang3.StringUtils; import java.util.Collection; impo ...

  5. 36. 解决线程问题方式一(同步代码块synchronized)

    解决线程问题: 方式一:同步代码块(synchronized) 语法: synchronized ("锁对象") {             //需要锁定的代码       }   ...

  6. [转]Netty入门(最简单的Netty客户端/服务器程序)

    Java中的NIO是一种解决阻塞式IO问题的基本技术,但是NIO的编写对java程序员是有比较高的要求的.那么Netty就是一种简化操作的一个成熟的网络IO编程框架.这里简单介绍一个程序,代码是< ...

  7. Dart编程语法

    语法定义了一组用于编写程序的规则.每种语言规范都定义了自己的语法.Dart语法有如下内容组成: 变量和运算符 类 函数 表达式和代码块 判断和循环结构 注释 库和包 类型定义 数据结构表示:集合/泛型 ...

  8. 27 和为S的两个数字

    0 引言 题目描述:输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的. 1 抽象问题具体化 举例: 序列为{1,2,3,4 ...

  9. delphi mysql

    Delphi2006连接Mysql5.1 2.DBExpress+dbxopenmysql50.dll可能很多人会奇怪,dbxopenmysql50.dll是什么东东?DBExpress不就是数据库连 ...

  10. Java-Class-@I:org.springframework.web.bind.annotation.RequestMapping

    ylbtech-Java-Class-@I:org.springframework.web.bind.annotation.RequestMapping 1.返回顶部   2.返回顶部 1. pack ...