Libcurl上传图片

最近使用C++做一些编程,JAVA中采用HTTP协议通信很简单,我们熟知的HTTPClient就可以完成通信。在C++中BOOST库仅仅将TCP/UDP协议进行了很好的封装,但是HTTP需要我们自己在编写一部分代码才能很好的同步HTTP来完成客户端与服务器端的信息交互。libcurl对HTTP等协议进行了很好的封装,于是采用libcurl来完成图片上传的功能。

1.libcurl简单认识

libcurl支持用不同的协议连接和沟通不同的服务器,其支持http, https, ftp, gopher, telnet, dict, file, 和ldap 协议。libcurl是C++中比较好的网络交互的库。

libcurl下载地址为:http://curl.haxx.se/download.html

libcurl 在线API地址为:http://curl.haxx.se/libcurl/c/

libcurl 接口介绍(中文)为:http://blog.csdn.net/fengshuiyue/article/details/39530093

2.libcurl图片上传源码

InnoVSSImgSendStateType InnoVSSImgNetStorage::NetStorageImg(PicStorageModel& picStorageModel)
	{
		curl = curl_easy_init();
		multi_handle = curl_multi_init();

		int still_running;

		struct curl_httppost *formpost=NULL;
		struct curl_httppost *lastptr=NULL;
		struct curl_slist *headerlist=NULL;
		static const char buf[] = "Expect:";

		curl_formadd(&formpost,
					&lastptr,
					CURLFORM_COPYNAME, "sendfile",
					CURLFORM_FILE, picStorageModel.picInfo.localPath.c_str(),
					CURLFORM_END);
		curl_formadd(&formpost,
					&lastptr,
					CURLFORM_COPYNAME, "filename",
					CURLFORM_COPYCONTENTS, picStorageModel.picInfo.fullView.c_str(),
					CURLFORM_END);

		std::string imageInfo;
		picStorageModel.postInfo.getImageInfoXml(imageInfo); 
		imageInfo = StringEncode::GBKToUTF8(imageInfo);

		curl_formadd(&formpost,
			&lastptr,
			CURLFORM_COPYNAME, "imageInfo",
			CURLFORM_COPYCONTENTS, imageInfo.c_str(),
			CURLFORM_END);

		std::string urlPath = picStorageModel.urlRequestPath;
		//headerlist = curl_slist_append(headerlist, "Accept-Encoding:UTF-8");
		//headerlist = curl_slist_append(headerlist, "Content-type: application/form-data;charset:UTF-8");
		headerlist = curl_slist_append(headerlist, buf);
		

		if(curl && multi_handle) {
			curl_easy_setopt(curl, CURLOPT_URL, urlPath.c_str());
			curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);

			curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
			curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);

			curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);
			//curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION,headerfunction);

			ImgNetStorageResultModel resultModel;
			resultModel.picStorageModel = picStorageModel;
			resultModel.imgNetStorage = this;
			curl_easy_setopt(curl, CURLOPT_WRITEDATA, &resultModel);

			curl_multi_add_handle(multi_handle, curl);

			CURLMcode curlm_code = CURLM_CALL_MULTI_PERFORM;
			curlm_code = curl_multi_perform(multi_handle, &still_running);

			int count = 0;
			int responseCode = 0;
			do {
				struct timeval timeout;
				int rc; 

				fd_set fdread;
				fd_set fdwrite;
				fd_set fdexcep;
				int maxfd = -1;

				long curl_timeo = -1;

				FD_ZERO(&fdread);
				FD_ZERO(&fdwrite);
				FD_ZERO(&fdexcep);

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

				curl_multi_timeout(multi_handle, &curl_timeo);
				if(curl_timeo >= 0) {
				timeout.tv_sec = curl_timeo / 1000;
				if(timeout.tv_sec > 1)
					timeout.tv_sec = 1;
				else
					timeout.tv_usec = (curl_timeo % 1000) * 1000;
				}

				curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);

				rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);

				switch(rc) {
				case -1:
					count++;
					break;
				case 0:
				default:
					LOGD << "正在上传图片....." << zhxy_log::endl;
					curlm_code = curl_multi_perform(multi_handle, &still_running);
					if (curlm_code ==  CURLM_OK){
						CURLcode res = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode);
					}
						
					break;
				}
				
			} while(still_running&&count < _adapterConfig.timeOutCount);

			//if (curlm_code == CURLM_OK) {
			//	long code;
			//	CURLcode res = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
			//	long connectCode;
			//	res = curl_easy_getinfo(curl, CURLINFO_HTTP_CONNECTCODE, &connectCode);
			//	LOGD << "connectCode:" << connectCode << zhxy_log::endl;
			//}
			curl_formfree(formpost);
			curl_slist_free_all (headerlist);
			curl_multi_cleanup(multi_handle);
			curl_easy_cleanup(curl);
			multi_handle = NULL;
			curl = NULL;
			if (curlm_code != CURLM_OK) {
				LOGD << "curlm_code:" <<  curlm_code << "\n" <<curl_multi_strerror(curlm_code);
				return InnoVSSImgSendStateTypes::Failed;
			}
			if (responseCode != 200)
			{
				return InnoVSSImgSendStateTypes::Failed;
			}
			if (count>=_adapterConfig.timeOutCount)
			{
				return InnoVSSImgSendStateTypes::Failed;
			}else{
				return InnoVSSImgSendStateType::Success;
			}
		}
	}

3.上传代码部分说明

1)在调试中发现不管图片服务器是否开启,curl_multi_perform(multi_handle, &still_running);返回值一直是成功,通过返回值无法捕获到上传是否成功。

2)代码中可以通过curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode);获取http相应值,在退出循环后判断responseCode是否为200,是则上传成功,否则上传失败


  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风水月

从心底相信自己是成功的第一步

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值