curl实现文件上传、下载

该文章提供了一个C++示例,展示了如何利用开源库CURL进行文件的下载和上传操作。在文件下载部分,通过CURL设置HTTP请求头、URL以及写入数据的回调函数来实现。在文件上传部分,文章演示了POST方法上传文件,并处理响应数据的回调函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 文件下载

#include <string>
#include "../../opensource/curl/include/curl/curl.h"

using namespace std;

size_t write_data(void* ptr, size_t size, size_t nmemb, void* stream) {
	size_t written = fwrite(ptr, size, nmemb, (FILE*)stream);
	return written;
}

/**
 * 
 * \brief  DownloadFile
 * \param url: http 服务器地址
 * \param save_path:下载文件保存路径
 * \return 0-成功,1-失败
 */
int DownloadFile(std::string url, std::string save_path) {
	CURL* curl;
	CURLcode res;
	
	FILE *file = fopen(save_path.c_str(), "wb");
	if (!file) {
		std::cerr << "Failed to create file: " << save_path << std::endl;
		return 1;
	}

	curl = curl_easy_init();
	if (curl) {
		//设置curl的请求头
		struct curl_slist* header_list = NULL;
		header_list = curl_slist_append(header_list, "User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko");
		curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list);

		//不接收响应头数据0代表不接收 1代表接收
		curl_easy_setopt(curl, CURLOPT_HEADER, 0);

		//设置请求的URL地址 
		curl_easy_setopt(curl, CURLOPT_URL, url.c_str());

		//设置ssl验证
		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);

		//CURLOPT_VERBOSE的值为1时,会显示详细的调试信息
		curl_easy_setopt(curl, CURLOPT_VERBOSE, 0);

		curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);

		curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &write_data);
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, file);

		curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);

		//设置超时时间
		curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 6); // set transport and time out time  
		curl_easy_setopt(curl, CURLOPT_TIMEOUT, 6);

		res = curl_easy_perform(curl);
		if (res != CURLE_OK) {
			std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl;
			return 1;
		}
		curl_easy_cleanup(curl);
	}

	fclose(file);

	return 0;
}

2. 文件上传

#include <string>
#include "../../opensource/curl/include/curl/curl.h"

using namespace std;

typedef struct
{
	bool                     send_state;     //发送的状态
	std::string              data;       //接收到的数据
} CURL_CMD;

//curl 调用的回调函数
 size_t response_callback(void *ptr, size_t size, size_t nmemb, void *stream)
{
	if (!stream) return (size * nmemb);
	CURL_CMD * Curl_Ptr = (CURL_CMD *)stream;
	Curl_Ptr->data.assign((char*)ptr, nmemb*size);
	Curl_Ptr->send_state = true;

	return (size * nmemb);
}

int UploadFile(string url, string file_path, void *response)
{
	CURL* curl;
	CURLcode res = CURLE_OK;
	/* In windows, this will init the winsock stuff */
	curl_global_init(CURL_GLOBAL_ALL);
	struct curl_slist* list = NULL;
	///* get a curl handle */
	curl = curl_easy_init();
	if (curl) {
		/* First set the URL that is about to receive our POST. This URL can
		just as well be a https:// URL if that is what should receive the
		data. */
		curl_easy_setopt(curl, CURLOPT_URL, url.c_str());

		/* Now specify the POST data */
		struct curl_httppost* post = NULL;
		struct curl_httppost* last = NULL;

		int pos = file_path.find_last_of("/");
		string file_name = file_path.substr(pos + 1, file_path.length());

		// form-data key(file) "./test.jpg"为文件路径  "hello.jpg" 为文件上传时文件名
		curl_formadd(&post, &last, CURLFORM_PTRNAME, "file", CURLFORM_FILE, file_path.c_str(), CURLFORM_FILENAME, file_name.c_str(), CURLFORM_END);
		//构造post参数
		curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);
		
		curl_easy_setopt(curl, CURLOPT_PORT, tcp_port);

		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, response_callback);
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, response);                 

		/* Perform the request, res will get the return code */
		res = curl_easy_perform(curl);
		/* Check for errors */
		if (res != CURLE_OK)
		{
			fprintf(stderr, "curl_easy_perform() failed: %s cmd=%s\n",
				curl_easy_strerror(res), strip);
		}

		/* always cleanup */
		curl_easy_cleanup(curl);
		curl_slist_free_all(list); /* free the list again */
	}

	curl_global_cleanup();

	return res;
}

int main()
{
	CURL_CMD cmd;
	cmd.send_state = false;
	UploadFile("http://192.168.1.88:80/upload", "image/1.jpg", &cmd);
	printf("send state:%d\n", cmd.send_state);
	printf("recv:%s\n", cmd.data.c_str());
	
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值