libcurl库的使用支持http、https、ftp(上传、下载、远端目录列表获取)

原创 2017年06月07日 13:16:59

这里是libcurl库的一个简单封装,支持跨平台。

声明:

    本文章可以转载,但必须注明源博客地址。共享的demo和curltools类不允许个人上传网络赚取积分和现金,如有发现必定追究责任,请慎重。


直接下载我上传的资源把curl文件夹解压到工程代码目录下导入curltools头文件和源文件到工程中,方可直接使用。

封装的源码下载地址http://download.csdn.net/download/wu110112/10180420

ftpdemo下载地址:http://download.csdn.net/download/wu110112/10180455


1、支持协议:http、https(短连接封装模式)

2、支持ca证书

3、支持表单提交

4、支持ftp上传/下载/远端目录列表获取(长连接封装模式)

5、支持STL string 字符全局替换功能


http调用如图:



FTP调用如图:


FTP效果如图:


头文件:

#pragma once
#include <string>
#include <vector>
#include "include/curl.h"
#include "include/easy.h"
#pragma comment(lib,"curl/lib/libcurl.lib")

/************************************************************************/
/*           libcurl库封装    ssdwujianhua 2017年6月7日 13:17:11      */
/************************************************************************/

//表单key对应的类型
enum E_KEY_TYPE {
	e_key_text,			//文本类型
	e_key_iamge			//图片类型
};

//表单信息结构
typedef struct 
{
	std::string strKey;
	std::string strVal;
	E_KEY_TYPE eKeyType;

	void Set(std::string key, std::string val, E_KEY_TYPE eType)
	{
		strKey = key;
		strVal = val;
		eKeyType = eType;
	}
}POST_LIST, *LPPOST_LIST;


//表单数据
#define  _POST_LIST_DATA_ std::vector<POST_LIST>
//转码相关函数
static std::string replace(const char *pszSrc, const char *pszOld, const char *pszNew);

class CUrlHttp
{
public:
	CUrlHttp(void);
	~CUrlHttp(void);
	static int Request(std::string strRequestType,
		std::string strUrl,
		std::string &strReport,
		std::string strParam="", 
		std::string strHeader="", 
		std::string strCookie="",  
		std::string strCaPath="",
		int nTimeOut=0);

	//有图片建议使用表单提交比较方便
	static int RequestSSL(std::string strUrl,
		std::string &strReport,
		_POST_LIST_DATA_ listParam, 
		std::string strHeader="", 
		std::string strCookie="",  
		std::string strCaPath="",
		int nTimeOut=0);
};

class CUrlFtp
{
public:
	CUrlFtp();
	~CUrlFtp();
	typedef struct 
	{
		size_t type;					//0:文件夹 1:文件
		std::string name;				//名称
		std::string permissions;		//权限
	}FILE_INFO, *LPFILE_INFO;
	
public:
	int connect(const char *user, const char *password, const char * ip, short port=21);
	void close();
	int download(const char * remoteFile, const char * localFile, size_t timeOut=0);
	int upload(const char * remoteFile, const char * localFile, size_t timeOut=0);
	int dirlist(const char * remote, std::vector<FILE_INFO> &vecFileInfo);
	const char * getLastError();

private:
		CURL *curl;
		std::string m_ip;
		std::string m_user;
		std::string m_password;
		short m_port;
		std::string m_lastError;
};





cpp文件

#include "curltools.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#ifdef WIN32
#include <io.h>
#else
#include <unistd.h>
#endif

//参数文档地址:https://curl.haxx.se/libcurl/c/libcurl-tutorial.html

namespace _CURL_
{  
	/**
	* buf: 从服务器返回的buffer
	* unit: buufer的单位
	* bufSize: buffer的大小
	* data: 保存从服务器返回的内容
	* 注意这个函数会被调用多次
	*/
	static size_t write_data(void *buf, size_t unit, size_t bufSize, std::string * data) 
	{
		int size = unit * bufSize;
		char * tmp = (char*)malloc(size + 1);
		memcpy(tmp, buf, size);
		tmp[size] = '\0';
		data->append(tmp);
		free(tmp);
		return size;
	}

	static size_t ftp_read(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;
	}

	//ftp 文件结构
	typedef struct FtpFile 
	{
		char filename[512];					//文件名称
		FILE *stream;						//文件操作指针
	}FTP_FILE, *LPFTP_FILE;

	static size_t ftp_write(void *buffer, size_t size, size_t nmemb,
		void *stream)
	{
		struct FtpFile *out = (struct FtpFile *)stream;
		if(out && !out->stream) {
			out->stream = fopen(out->filename, "wb");
			if(!out->stream)
				return -1; 
		}
		return fwrite(buffer, size, nmemb, out->stream);
	}




	//智能初始化curl库和释放curl库
	class CurlIntelligence
	{
	public:
		CurlIntelligence()
		{
			curl_global_init(CURL_GLOBAL_ALL);
		}

		~CurlIntelligence()
		{
			curl_global_cleanup();
		}
	};
}

_CURL_::CurlIntelligence g_curl;

/*
 *	函数:
 *		 replace(替换字符串)
 *  参数:
 *		pszSrc:源字符串
 *		pszOld:需要替换的字符串
 *		pszNew:新字符串
 *  返回值:
 *		返回替换后的字符串
 * ssdwujianhua 2017/12/04 
 */
std::string replace(const char *pszSrc, const char *pszOld, const char *pszNew)  
{  
    std::string strContent, strTemp;  
    strContent.assign( pszSrc );  
    std::string::size_type nPos = 0;  
    while( true )  
    {  
        nPos = strContent.find(pszOld, nPos);  
		if ( nPos == std::string::npos )  
		{  
			break;  
		}  
        strTemp = strContent.substr(nPos+strlen(pszOld), strContent.length());  
        strContent.replace(nPos,strContent.length(), pszNew );  
        strContent.append(strTemp);  
        nPos +=strlen(pszNew) - strlen(pszOld)+1; //防止重复替换 避免死循环  
    }  
    return strContent;  
} 

CUrlHttp::CUrlHttp(void)
{
}

CUrlHttp::~CUrlHttp(void)
{
}

/*
 *	函数:
 *		 Request(请求函数)
 *  参数:
 *		strRequestType:请求类型(get,post)
 *		strUrl:请求url地址
 *		strReport:回执信息
 *		strHeader:请求头
 *		strCookie:cookie信息
 *		strCaPath:ca转成pem证书路径
 *		strParam:请求参数(get的时候此参数填空)
 *		nTimeOut:超时设置默认是0秒 是无限等待
 *  返回值:
 *		0表示成功 非0表示错误代码
 * ssdwujianhua 2017/06/06 
 */
int CUrlHttp::Request(std::string strRequestType,
					  std::string strUrl,
					  std::string &strReport,
					  std::string strParam/* ="" */, 
					  std::string strHeader/* ="" */, 
					  std::string strCookie/* ="" */, 
					  std::string strCaPath/* ="" */,
					  int nTimeOut/* =0 */)
{
	CURL * curl;
	curl = curl_easy_init();
	curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());
	
	if ( strRequestType.compare("post")==0 || strRequestType.compare("POST") == 0 )
	{
		curl_easy_setopt(curl, CURLOPT_POST, 1);
		curl_easy_setopt(curl, CURLOPT_POSTFIELDS, strParam.c_str());
	}
	else
	{
		curl_easy_setopt(curl, CURLOPT_POST, 0);//get请求
	}

	//判断是否有证书
	if(strCaPath.empty())
	{
		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
	}
	else
	{
		//缺省情况就是PEM,所以无需设置,另外支持DER
		//curl_easy_setopt(curl,CURLOPT_SSLCERTTYPE,"PEM");
		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, true);
		curl_easy_setopt(curl, CURLOPT_CAINFO, strCaPath.c_str());
	}

	std::string strReportHeader;//回执回来的头数据
	curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);		//可以看到调试信息
	//接受服务器的ssl证书而不管合不合法 (相当于命令行中的--insecure)
	curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
	curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
	//curl_easy_setopt(curl,CURLOPT_HEADERFUNCTION,_CURL_::write_data);
	//curl_easy_setopt(curl, CURLOPT_WRITEHEADER, &strReportHeader);
	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _CURL_::write_data);
	curl_easy_setopt(curl, CURLOPT_WRITEDATA, &strReport); 
	if ( nTimeOut > 0  )
	{
		curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, nTimeOut);
		curl_easy_setopt(curl, CURLOPT_TIMEOUT, nTimeOut);
	}
	
	curl_slist * headers = NULL;
	if (!strHeader.empty())
	{
		headers = curl_slist_append(headers, strHeader.c_str());
		curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
	}

	if (!strCookie.empty())
	{

		curl_easy_setopt(curl, CURLOPT_COOKIEFILE, strCookie.c_str());
	}
	CURLcode code = curl_easy_perform(curl);
	if ( headers != NULL )
	{
		curl_slist_free_all(headers);
	}
	curl_easy_cleanup(curl);
	//打印出来
// 	std::string strReportData;
// 	strReportData.append(strReportHeader);
// 	strReportData.append(strReport);
// 	TRACE("request:%s  url:%s report:%s", strRequestType.c_str(), strUrl.c_str(), strReportData.c_str());
	return code;
}

/*
 *	函数:
 *		 RequestSSL(表单提交)
 *  参数:
 *		strUrl:请求url地址
 *		strReport:回执信息
 *		strHeader:请求头
 *		strCookie:cookie信息
 *		listParam:表单列表
 *		strCaPath:ca转成pem证书路径
 *		nTimeOut:超时设置默认是0秒 是无限等待:
 *  返回值:
 *		0表示成功 非0表示错误代码
 * ssdwujianhua 2017/07/21 
 */
int CUrlHttp::RequestSSL(std::string strUrl, 
						 std::string &strReport, 
						 _POST_LIST_DATA_ listParam, 
						 std::string strHeader/* ="" */, 
						 std::string strCookie/* ="" */, 
						 std::string strCaPath/* ="" */, 
						 int nTimeOut/* =0 */)
{
	CURLcode code;
	CURL * curl;
	curl = curl_easy_init();
	curl_easy_setopt(curl, CURLOPT_POST, 1);
	curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());  
	//err = curl_easy_setopt(hCurl, CURLOPT_HTTPHEADER, "dfsdf");   
	struct curl_httppost *post=NULL;        
	struct curl_httppost *last=NULL;      

	CURLFORMcode errf; 
	for ( int i=0; i<listParam.size(); i++ )
	{
		POST_LIST post_list = listParam.at(i);
		if (post_list.eKeyType == e_key_iamge ) //图片类型 直接提交图片路径
		{
			errf = curl_formadd(&post, &last,   CURLFORM_COPYNAME, post_list.strKey.c_str(),   
				CURLFORM_FILE,post_list.strVal.c_str(),CURLFORM_CONTENTTYPE, "image/jpeg",CURLFORM_END);
		}
		else
		{
			errf = curl_formadd(&post, &last,  CURLFORM_COPYNAME, post_list.strKey.c_str(),   
				CURLFORM_COPYCONTENTS, post_list.strVal.c_str(),CURLFORM_END); 
		}


	}
	

	curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);        
	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _CURL_::write_data);       
	curl_easy_setopt(curl, CURLOPT_WRITEDATA, &strReport);         
	curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); 

	//判断是否有证书
	if(strCaPath.empty())
	{
		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
	}
	else
	{
		//缺省情况就是PEM,所以无需设置,另外支持DER
		//curl_easy_setopt(curl,CURLOPT_SSLCERTTYPE,"PEM");
		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, true);
		curl_easy_setopt(curl, CURLOPT_CAINFO, strCaPath.c_str());
	}

	//设置超时时间
	if ( nTimeOut > 0  )
	{
		curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, nTimeOut);
		curl_easy_setopt(curl, CURLOPT_TIMEOUT, nTimeOut);
	}       
	curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION,1); //是否抓取跳转后的页面       
	/* Set the form info */          
	curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);    //  
	curl_easy_setopt(curl, CURLOPT_HEADER, 0);  //不读取返回头的数据

	//设置http头
	curl_slist * headers = NULL;
	if (!strHeader.empty())
	{
		headers = curl_slist_append(headers, strHeader.c_str());
		curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
	}

	//设置http cookie
	if (!strCookie.empty())
	{
		curl_easy_setopt(curl, CURLOPT_COOKIEFILE, strCookie.c_str());
	}
	code = curl_easy_perform(curl); /* post away! */       
	//获取请求返回的值  如:200
	//code = curl_easy_getinfo(curl,CURLINFO_RESPONSE_CODE, &RESPONSE_CODE);
	/* free the post data again */
	if ( headers != NULL )
	{
		curl_slist_free_all(headers);
	}
	curl_formfree(post);            
	curl_easy_cleanup(curl);
	return code;
}


 

/********************************************************************************************
*									curl FTP 类封装											*	
*
*
*********************************************************************************************/
CUrlFtp::CUrlFtp()
{
	curl = NULL;
}

CUrlFtp::~CUrlFtp()
{
	close();
}

/*
 *	函数:
 *		 connect(ftp连接)
 *  参数:
 *		user:ftp帐号
 *		password:ftp密码
 *		ip:ftpip
 *		port:ftp端口
 *  返回值:
 *		成功返回0 失败返回-1
 * ssdwujianhua 2017/12/29 
 */
int CUrlFtp::connect( const char *user, const char *password, const char * ip, short port /*=21*/)
{
	curl = curl_easy_init();
	if ( curl == NULL )
	{
		m_lastError.assign("curl initialization failure!");
		printf("curl initialization failure!\n");
		return -1;
	}

	//设置登录帐号和密码
	std::string spider;
	spider.append(user);
	spider.append(":");
	spider.append(password);
	curl_easy_setopt(curl, CURLOPT_USERPWD, spider.c_str());

	std::string url;
	url.append("ftp://");;
	url.append(ip);
	if ( port != 0  )
	{
		url.append(":");
		char szPort[10];
		sprintf(szPort, "%d", port);
		url.append(szPort);
	}
	curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
	curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);

	CURLcode code = curl_easy_perform(curl);
	if ( code != CURLE_OK )
	{
		m_lastError = curl_easy_strerror( code );
		printf("ftp connect failure: %s!\n", m_lastError.c_str());
		close();
		return -1;
	}
	m_ip.assign(ip);
	m_user.assign(user);
	m_password.assign(password);
	m_port = port;
	m_lastError.assign("ftp connect success!");
	printf("ftp connect success!\n");
	return 0;
}

/*
 *	函数:
 *		 close(ftp关闭)
 *  参数:
 *		无
 *  返回值:
 *		无
 * ssdwujianhua 2017/12/29 
 */
void CUrlFtp::close()
{
	if ( curl != NULL )
	{
		curl_easy_cleanup(curl);
		curl = NULL;
	}
}

/*
 *	函数:
 *		 download(ftp文件下载)
 *  参数:
 *		remoteFile:远端文件路径
 *		localFile:本地文件路径
 *		timeOut:超时时间 单位秒
 *  返回值:
 *		成功返回0 失败返回-1
 * ssdwujianhua 2017/12/29 
 */
int CUrlFtp::download(const char * remoteFile, const char * localFile, size_t timeOut /*= 0*/)
{
	if ( curl == NULL )
	{
		m_lastError.assign("ftp disconnect!");
		printf("ftp disconnect!");
		return -1;
	}
	std::string newRemotePath = replace(remoteFile, "\\", "/" );
	std::string newLocalPath = replace(localFile, "\\", "/" );
	_CURL_::FTP_FILE ftpfile;
	sprintf(ftpfile.filename, "%s",newLocalPath.c_str());
	ftpfile.stream = NULL;
	std::string url;
	url.append("ftp://");;
	url.append(m_ip);
	url.append(":");
	char szPort[10];
	sprintf(szPort, "%d", m_port);
	url.append(szPort);
	url.append("/");
	url.append(newRemotePath);
	curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _CURL_::ftp_write);
	curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
	curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
	if ( timeOut > 0 )
	{
		curl_easy_setopt(curl, CURLOPT_FTP_RESPONSE_TIMEOUT, timeOut);
	}
	CURLcode code = curl_easy_perform(curl);
	if ( code != CURLE_OK )
	{
		m_lastError = curl_easy_strerror( code );
		printf("ftp download failure: %s!\n", m_lastError.c_str());
		return -1;
	}
	m_lastError.assign("ftp upload success!");
	return 0;
}

/*
 *	函数:
 *		 upload(ftp文件上传)
 *  参数:
 *		remoteFile:远端文件路径
 *		localFile:本地文件路径
 *		timeOut:超时时间 单位秒
 *  返回值:
 *		成功返回0 失败返回-1
 * ssdwujianhua 2017/12/29 
 */
int CUrlFtp::upload(const char * remoteFile, const char * localFile, size_t timeOut/*=0*/)
{
	if ( curl == NULL )
	{
		m_lastError.assign("ftp disconnect!");
		printf("ftp disconnect!");
		return -1;
	}
	std::string newRemotePath = replace(remoteFile, "\\", "/" );
	std::string newLocalPath = replace(localFile, "\\", "/" );

	CURLcode code;
	FILE *hd_src;
	struct stat file_info;
	curl_off_t fsize;

	std::size_t nItem = newRemotePath.find_last_of("/");
	std::string remoteFileName = newRemotePath.substr(nItem+1);//文件名称
	std::string remotePath = newRemotePath.substr(0, nItem);//远端路径

	struct curl_slist *headerlist = NULL;
	char buf_1 [256] = "RNFR while-uploading";
	char buf_2 [256];	//远端文件名称
	sprintf(buf_2,"RNTO %s", remoteFileName.c_str());
	if(stat(newLocalPath.c_str(), &file_info)) 
	{
		m_lastError.assign("the uploaded file does not exist!");
		printf("the uploaded file does not exist(%s)!\n", localFile);
		return -1;
	}
	fsize = (curl_off_t)file_info.st_size;
	hd_src = fopen(newLocalPath.c_str(), "rb");
	if ( hd_src == NULL )
	{
		m_lastError.assign("file open failed!");
		printf("file open failed(%s)!\n", localFile);
		return -1;
	}
	
	headerlist = curl_slist_append(headerlist, buf_1);
	headerlist = curl_slist_append(headerlist, buf_2);
	curl_easy_setopt(curl, CURLOPT_READFUNCTION, _CURL_::ftp_read);
	curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
	//设置ftp url
	std::string url = "ftp://";
	url.append(m_ip);
	url.append(":");
	char szPort[10];
	sprintf(szPort, "%d", m_port);
	url.append(szPort);
	url.append("/");
	url.append(remotePath);
	url.append("/");
	url.append("while-uploading");
 	curl_easy_setopt(curl, CURLOPT_URL, url.c_str());  
	curl_easy_setopt(curl, CURLOPT_POSTQUOTE, headerlist);
	curl_easy_setopt(curl, CURLOPT_READDATA, hd_src);
	curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,(curl_off_t)fsize);

	if ( timeOut > 0 )
	{
		curl_easy_setopt(curl, CURLOPT_FTP_RESPONSE_TIMEOUT, timeOut);
	}
	code = curl_easy_perform(curl);
	curl_slist_free_all(headerlist);
	if ( code != CURLE_OK )
	{
		fclose(hd_src);
		m_lastError = curl_easy_strerror( code );
		printf("ftp upload failure: %s!\n", m_lastError.c_str());
		return -1;
	}
	fclose(hd_src); 
	m_lastError.assign("ftp upload success!");
	return code;
}

/*
 *	函数:
 *		 dirlist(远端目录列表获取)
 *  参数:
 *		remote:远端目录路径
 *		vecFileInfo:输出遍历得到的文件夹和文件
 *  返回值:
 *		成功返回0 失败返回-1
 * ssdwujianhua 2017/12/29 
 */
int CUrlFtp::dirlist(const char * remote, std::vector<FILE_INFO> &vecFileInfo)
{
	if ( curl == NULL )
	{
		m_lastError.assign("ftp disconnect!");
		printf("ftp disconnect!");
		return -1;
	}
	std::string remotePath = replace(remote, "\\", "/" );
	if ( remotePath.size() == 0 )
	{
		remotePath.append("/");
	}
	if ( remotePath[remotePath.length()-1] != '/')
	{
		remotePath.append("/");
	}
	std::string url;
	url.append("ftp://");;
	url.append(m_ip);
	url.append(":");
	char szPort[10];
	sprintf(szPort, "%d", m_port);
	url.append(szPort);
	url.append("/");
	url.append(remotePath);
	std::string response;
	curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
	curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _CURL_::write_data);       
	curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); 
	CURLcode code = curl_easy_perform(curl);
	if ( code != CURLE_OK )
	{
		m_lastError = curl_easy_strerror( code );
		printf("ftp connect failure: %s!\n", m_lastError.c_str());
		return -1;
	}
	//解析ftp数据得到文件和文件夹属性
	std::string::size_type pos=0, index=0, len=0;
	while( true )  
	{  
		std::string row= "";
		pos = response.find("\r\n", pos)+2;
		if ( pos < index )  
		{  
			break;  
		}  
		len =  pos - index;//需要截取的字符串长度
 		row = response.substr(index, len); //得到每行数据
		index = pos;

		std::string::size_type rowPos=0, rowIndex=0, rowLen=0;
		//得到名称
		FILE_INFO fileInfo;
		rowPos = row.find_last_of(' ')+1; 
		std::string name = row.substr(rowPos, row.length());
		if ( name.size() == 0 || name[0] == '.')
		{
			continue;
		}
		
		fileInfo.name = name;
		//得到文件权限和文件类型
		rowPos = row.find_first_of(' ');
		std::string data = row.substr(0,rowPos);
		if ( data.size() != 0 )
		{
			if (data[0] == 'd')
			{
				//文件夹
				fileInfo.type = 0;
				fileInfo.permissions = data.substr(1, data.length());
			}
			else 
			{
				//文件
				fileInfo.type = 1;
				fileInfo.permissions = data.substr(1, data.length());
			}
			
		}

		vecFileInfo.push_back(fileInfo);
	}  
	m_lastError.assign("");
	return 0;
}

/*
 *	函数:
 *		 getLastError(最后错误信息)
 *  参数:
 *		无
 *  返回值:
 *		对应的错误信息
 * ssdwujianhua 2017/12/29 
 */
const char * CUrlFtp::getLastError()
{
	return m_lastError.c_str();
}






版权声明:本文为博主原创文章,未经博主允许不得转载。

libcurl 如何支持https

执行curl_easy_perform()的时候,返回错误代码:CURLE_UNSUPPORTED_PROTOCOL(1),同时通过打印日志会得到错误提示:" Protocol https not...
  • hellokandy
  • hellokandy
  • 2016年04月27日 20:49
  • 10464

libcurl进行https的post参数

用libcurl进行开发,想实现与https的站点的交互
  • zhuxian2009
  • zhuxian2009
  • 2014年11月16日 13:55
  • 1974

libcurl 通过http协议下载文件并显示下载进度

vc6 测试工程下载地址:  代码如下: size_t my_write_func(void *ptr, size_t size, size_t nmemb, FILE *stre...
  • mtour
  • mtour
  • 2014年10月22日 14:22
  • 2344

curl可访问https(已编译库文件)内有说明文档和测试源码,亲测可用

  • 2016年05月19日 07:28
  • 2.44MB
  • 下载

使用libcurl库编写HTTP客户端(包括GET/POST/HTTPS)

最近在写一个应用程序, 需要与HTTP服务器进行数据交互, 于是乎自己写了一个类似wget的功能的客户端, 实现很简单, 但是功能不给力, 只可基本功能. 于是又在网上找了找, 发现使用libcurl...
  • xulei364132789
  • xulei364132789
  • 2015年03月26日 15:46
  • 5313

libcurl使用认证证书 https认证

在server.xml中增加下面的内容: [cpp] view plaincopyprint? ciphers="SSL_RSA_WITH_RC4_12...
  • chary8088
  • chary8088
  • 2014年04月04日 17:36
  • 9870

http请求下载文件

最近遇到一个请求需要从数据库查询出来,然后点击下载,可以下载从数据库查询的的数据,并换行显示。 @RequestMapping("downLoadCardListByCardType") pu...
  • u010552708
  • u010552708
  • 2015年12月15日 17:31
  • 2294

LINUX命令行下以HTTP方式下载文件的方法

顺便提一下。如果下载ftp服务器上的文件,可以用ftp命令。然后用get命令下载文件   对于喜欢命令行操作及追求高效率、高速度下载的朋友,推荐使用命令行下载工具。命令行工具不但使用方便,而且大...
  • qing101hua
  • qing101hua
  • 2017年08月13日 16:40
  • 1476

使用libcurl 支持https

刚好工作上需要编写客户端的程序,原本封装好的http程序代码突然异常了,百思不得其解。 然后再http client的代码中打印可能出现的异常,终于在下面的代码中捕获出来。 res = curl_ea...
  • aceai
  • aceai
  • 2014年12月26日 11:34
  • 370

Libcurl的编译_HTTP/HTTPS客户端源码示例

libcurl的编译,及HTTP/HTTPS客户端源码示例,支持文件上传和下载。
  • lee353086
  • lee353086
  • 2014年10月21日 19:21
  • 7919
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:libcurl库的使用支持http、https、ftp(上传、下载、远端目录列表获取)
举报原因:
原因补充:

(最多只允许输入30个字)