curl手动中断上传

25 篇文章 0 订阅
7 篇文章 1 订阅
#if LIBCURL_VERSION_NUM >= 0x073d00
/* In libcurl 7.61.0, support was added for extracting the time in plain
microseconds. Older libcurl versions are stuck in using 'double' for this
information so we complicate this example a bit by supporting either
approach. */ 
#define TIME_IN_US 1  
#define TIMETYPE curl_off_t
#define TIMEOPT CURLINFO_TOTAL_TIME_T
#define MINIMAL_PROGRESS_FUNCTIONALITY_INTERVAL     3000000
#else
#define TIMETYPE double
#define TIMEOPT CURLINFO_TOTAL_TIME
#define MINIMAL_PROGRESS_FUNCTIONALITY_INTERVAL     3
#endif
#define STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES         6000

typedef struct myprogress {
	TIMETYPE lastruntime; /* type depends on version, see above */ 
	CURL *curl;
	int* pContinue;
	__int64* ulnow;
	__int64* ultotal;
	double* speed;	
}myprogress;

/* this is how the CURLOPT_XFERINFOFUNCTION callback works */ 
static int xferinfo(void *p,
	curl_off_t/* dltotal*/, curl_off_t dlnow,
	curl_off_t ultotal, curl_off_t ulnow)
{
	struct myprogress *myp = (struct myprogress *)p;
	CURL *curl = myp->curl;
	TIMETYPE curtime = 0;

	curl_easy_getinfo(curl, TIMEOPT, &curtime);

	curl_easy_getinfo(curl, CURLINFO_SPEED_UPLOAD, myp->speed);

	*(myp->ulnow) = ulnow;

	*(myp->ultotal) = ultotal;

	if(dlnow > STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES)
		return 1;
	if (*(myp->pContinue) == 0)
		return 1;
	return 0;
}

// 上传函数
CURLcode CHttpClient::UploadEx(const wchar_t* file_path_name, const wchar_t* remote_url, std::wstring& output, int* pContinue, __int64* pnow, __int64* ptotal, double* pSpeed)
{
	CURLcode code = CURLE_FAILED_INIT;  

	CURL* curl = curl_easy_init();  
	if(curl) 
	{
		std::vector<char> buffer;

		struct curl_httppost * post = NULL;
		struct curl_httppost * last = NULL;
		struct myprogress prog;
		prog.lastruntime = 0;
		prog.curl = curl;
		prog.pContinue = pContinue;
		prog.ulnow = pnow;
		prog.ultotal = ptotal;
		prog.speed = pSpeed;

		// 添加上传的本地文件
		curl_formadd(&post, &last,
			CURLFORM_COPYNAME, "filename",  
			CURLFORM_FILE, common::wstring_to_string(file_path_name).c_str(),
			CURLFORM_CONTENTTYPE, "application/octet-stream",
			CURLFORM_END);  

		// 设置上传的其他参数
		std::map<std::string, std::string>::const_iterator it;
		for (it = m_mapPostFields.begin(); it != m_mapPostFields.end();it++)
		{
			curl_formadd(&post, &last,
				CURLFORM_COPYNAME, it->first.c_str(),  
				CURLFORM_COPYCONTENTS, it->second.c_str(),
				CURLFORM_END);  
		}
		//curl_easy_setopt(curl, CURLOPT_POSTFIELDS, StringfyFields(m_mapPostFields).c_str());

		// 输出调试信息
		curl_easy_setopt(curl, CURLOPT_VERBOSE, VERBOSE_FLAG);

		// 设置上传的URL
		std::string url = common::encodeURI(common::wstring_to_utf8(remote_url));

		curl_easy_setopt(curl, CURLOPT_URL, url.c_str());  

		// 设置超时时间
		curl_easy_setopt(curl, CURLOPT_TIMEOUT, m_nTimeout);

		// 设置连接时间为30秒
		curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30);

		// 设置允许追踪重定向
		curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);

		// 设置为执行POST请求
		curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);

		// 设置回调函数
		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteDataCallback);

		// 设置获取到的数据的指针
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);

		// 设置是否关闭传输进度
		curl_easy_setopt(curl, CURLOPT_NOPROGRESS, false);

		// 设置进度回调函数
		curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, xferinfo);

		// 设置进度函数使用指针
		curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &prog);

		code = curl_easy_perform(curl);

		if (code != CURLE_OK)
		{
			fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(code));
		}

		curl_easy_cleanup(curl);  

		curl_formfree(post);

		std::string strBuffer(buffer.begin(), buffer.end());
		output = common::utf8_to_wstring(strBuffer.c_str());
	}

	return code;
}

在外部修改pContinue所指向的值为0即可中断。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值