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

时间: 2024-08-24 14:42:44

Libcurl上传图片的相关文章

c/c++/curl实现facebook上传图片等功能

翻了下以前的日记,决定把一些笔记晒出来分享,需求是这样,需要通过c/c++写的应用实现上传图片等到facebook,以下是用curl模拟的登录facebook,并取得权限的一些记录,有可能facebook的接口已经改了,但是原理是一样的,能用curl命令实现,c/c++就可以调用libcurl来实现程序控制的. 要有权限就得有access token 得到access token的一种方式 1. Embed a web browser and implement the client-side

本地上传图片预览

<!DOCTYPE html > <html > <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>图片上传本地预览,获得图片的base64(可压缩)</title> <style type="text/css"> .upload_image {

java web应用用户上传图片的存储地址

原来工程的上传图片存储地址在web应用的目录下,并且是硬编码到其中的: 每次使用maven tomcat:redeploy以后,这个目录就没有了. 现在想要把上传图片的位置移动到tomcat的webapps目录中专门存放图片的一个目录下. 即,新建的一个images目录用来存放web应用的图片们. 这样就把工程和用户上传图片分离了,以后在redeploy时也不用预先备upload目录,然后再拷贝回去,因而在web应该更新时比较方便些.此外,还想改变文件路径被硬编码到java文件中的现状,所以将文

微信JS-SDK实现上传图片功能

最近在项目开放中,有一个在微信WEB项目中上传图片的需求,一开始使用了传统的<input type="file">的方式去实现,但是后面发现在使用这种传统模式时会由于手机系统的差异而导致一系列的问题,后改用微信JSSDK的方式来实现. 总的来说,利用JSSDK来实现该功能一共分为四步. 1. 调用wx.config(),初始化jssdk的配置,并在jsApiList中配置上传图片需要的四个api('chooseImage','previewImage','uploadIma

jquery html5 file 上传图片显示图片

最近做了一个小例子,在上传用户图像时,如何在上传图片时显示图片.在网上找了很多资料也未能如愿,如是,就用jquery ,html5,实现了,由于开发是在linux 所以未能在ie下测试,在forefox,chrom下是可以的. 一.html下的代码是: <div class=' input_box' > <span class='spac' >头</span>相:<input class="input_style" id="'head

jquery实现上传图片及图片大小验证、图片预览效果代码

jquery实现上传图片及图片大小验证.图片预览效果代码 上传图片验证 */ function submit_upload_picture(){     var file = $('file_c').value;     if(!/.(gif|jpg|jpeg|png|gif|jpg|png)$/.test(file)){            alert("图片类型必须是.gif,jpeg,jpg,png中的一种")        }else{      $('both_form')

检验上传图片大小、尺寸、类型的两种实现方案

做图片上传功能时,我们经常会遇到一个问题就是,就是要对上传的图片进行一个校验,校验的东西包括图片的大小.尺寸(即宽和高)以及图片的类型. 今天我主要介绍两种方式来进行图片的校验,一种是在前端用js校验,另一种是放在服务器端校验.接下来我们来进行介绍 第一种:放在前端用js校验 下面直接贴源代码,注释也写在代码里面 1 <%@ page language="java" contenttype="text/html; charset=UTF-8" pageenco

js 上传图片本地预览缓存

<!DOCTYPE html><html><head> <meta charset="UTF-8"> <title>文件上传</title> <script src="jQuery.js"></script> <style type="text/css"> #file{ display: block; width: 400px; heigh

vue-update-表单形式复写方法上传图片

handleSave() { const formData = new FormData(); /* eslint-disable */ for (let key in this.dataInfo) { if (Object.prototype.hasOwnProperty.call(this.dataInfo, key)) { formData.append(key, this.dataInfo[key]); } } let para = { headers: {'content-type':