C++之Libcurl库实现HTTP协议传输数据

        一直想写一些关于C++的博客,却一直没抽空来写,今天趁着代码打累了,来写写年前想写的博客。       
        在做项目时,因为我使用的后台是用.net core写的,那么C++就需要使用http协议来同后台进行交互了。C++要如何使用http协议呢?这里我推荐使用Libcurl这个库,不得不说这个库真的很强大( 有兴趣的小伙伴可以去查阅查阅),当然也可以使用其他的,下面我们进入正题。
       首先大家先到网上下载libcurl,大家自行 下载,密码: zsrb,博主这里用的是curl-7.26.0的,将“ curl-7.26.0/include/curl文件夹拷贝到自己的项目中,该文件夹包含了curl需要的头文件,为了方便起见我将curl的库文件也拷贝到了项目中,并放在了刚刚的curl中,库文件的地址“curl-7.26.0/lib/Debug”和"curl-7.26.0/lib/Release"。下面我们在项目中引入curl:  
//引入头文件
#include "curl\curl.h"
#include "curl\easy.h"
下面我们就来说说curl的使用。
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();

curl_global_init()用以初始化curl环境,curl_easy_init用来初始化一个easy curl对象。

#ifdef _DEBUG
    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
#endif
    curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);	
    curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);

curl_easy_setopt是对easy curl对象进行相关设置,需要设置哪些参数可以自行查阅。这事可以直接使用curl_easy_perform执行curl请求,但这种情况是阻塞的,所以下面我会介绍multi执行并发请求。先来看看代码

bool CLibcurl::UserLand(const std::string number, const std::string password)
{
	std::string  strUrl = "http://*******/User/Login";        // 接口地址
	CURL *curl;
	CURLM *multi_handle;
	std::stringstream getstream;
	int still_running;
	bool IsTrue = false;

	struct curl_httppost *formpost = NULL;
	struct curl_httppost *lastptr = NULL;
	struct curl_slist	 *headers = NULL;
	static const char buf[] = "Expect:";
	curl_global_init(CURL_GLOBAL_ALL);
	curl_formadd(&formpost, &lastptr,
		CURLFORM_COPYNAME, "username",
		CURLFORM_COPYCONTENTS, number.c_str(),
		CURLFORM_END);
	curl_formadd(&formpost, &lastptr,
		CURLFORM_COPYNAME, "password",
		CURLFORM_COPYCONTENTS, password.c_str(),
		CURLFORM_END);
		
	curl = curl_easy_init();
	multi_handle = curl_multi_init();
	if (NULL == curl || NULL == multi_handle) {		
		IsTrue = false;
		goto exit;
	}			

	headers = curl_slist_append(headers, buf);
#ifdef _DEBUG
	curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
#endif
	curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());
	curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);	
	curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);    // 表单
	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
	curl_easy_setopt(curl, CURLOPT_WRITEDATA, &getstream);

	curl_multi_add_handle(multi_handle, curl);

	while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(multi_handle, &still_running));
	while (still_running) {
			
		switch (Select(multi_handle)) {
		case -1:
			break;
		case 0:
			std::cout << "timeout" << std::endl;
		default:
			while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(multi_handle, &still_running));
			break;
		}
	}

	//对接收到的getstream进行处理

exit:	
	curl_global_cleanup();
	curl_multi_cleanup(multi_handle);
	curl_easy_cleanup(curl);
	curl_formfree(formpost);
	curl_slist_free_all(headers);

	return IsTrue;
}

下面我们来分析下这个代码,此处我写的是一个简单的提交登陆表单的程序,使用curl_formadd()来构建表单,是不是发现表单构建起来变得很简单了,突然有了写javascript的感觉。curl_formadd中的 CURLFORM_COPYNAME,是后台接收时的字段名,而CURLFORM_COPYCONTENTS则是存储字段名对应的内容,比如用户的用户名,想了解更多可点击该链接。 使用multi前我们还需要用curl_multi_init()先初始化multi,虽然说multi是并发的,但其实它的使用也是非常简单的,只需将我们上面使用curl_easy_init创建的curl传入到curl_slist_append的第二个参数中就行了,接下来我们就可以用curl_multi_perform执行multi了,此处使用的是select来对事件进行监听,并通知curl执行对应操作。

上面代码中的Select函数代码如下:

int CLibcurl::Select(CURLM *multi_handle)
{
	struct timeval timeout;
	int rc;
	fd_set fdread;
	fd_set fdwrite;
	fd_set fdexcep;
	int maxfd;
	FD_ZERO(&fdread);
	FD_ZERO(&fdwrite);
	FD_ZERO(&fdexcep);

	timeout.tv_sec = 1;
	timeout.tv_usec = 0;

	// 获取文件描述符
	curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
	rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);

	return rc;
}

最后补充下,在构建表单的时候可以将文件传入表单中

curl_formadd(&formpost, &lastptr, 
	CURLFORM_COPYNAME, "data",
	CURLFORM_FILE, filepath.c_str(),        // 文件的所在地址
	CURLFORM_END);
可以用这种方法来实现小文件的简单上传,curl的用法大致就说到这里了,想深入研究的朋友可以积极查阅资料。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值