码迷,mamicode.com
首页 > 其他好文 > 详细

Libcurl上传图片

时间:2014-09-24 23:53:37      阅读:359      评论:0      收藏:0      [点我收藏+]

标签:libnfc   c++   

最近使用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,是则上传成功,否则上传失败


Libcurl上传图片

标签:libnfc   c++   

原文地址:http://blog.csdn.net/fengshuiyue/article/details/39529887

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!