欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

libcurl 文件上传下载实例

程序员文章站 2022-03-11 20:07:41
...

vs环境

使用libcurl静态链接库

生成静态链接库参考:Windows系统 libcurl静态链接环境配置(不带ssl)

#include<iostream>
#include<string>
#include<ctime>
#include "curl/curl.h"

int nMethod = -1;
char szFileFrom[64] = "";

int uploadfile()
{
	CURL *curl;

	CURLM *multi_handle;
	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_PTRNAME, "file",
		//CURLFORM_FILE, "C:\\SMGConfig.ini",
		CURLFORM_FILE, szFileFrom,
		CURLFORM_END);

	curl = curl_easy_init();
	multi_handle = curl_multi_init();

	/* initalize custom header list (stating that Expect: 100-continue is not
	   wanted */
	headerlist = curl_slist_append(headerlist, buf);
	if (curl && multi_handle) {
		/* what URL that receives this POST */
		curl_easy_setopt(curl, CURLOPT_URL, "http://172.16.20.48/API/upload.php");
		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_USERPWD, "ApiUserAdmin:123456");

		curl_multi_add_handle(multi_handle, curl);

		curl_multi_perform(multi_handle, &still_running);

		do {
			struct timeval timeout;
			int rc; /* select() return code */

			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);

			/* set a suitable timeout to play around with */
			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;
			}

			/* get file descriptors from the transfers */
			curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);

			/* In a real-world program you OF COURSE check the return code of the
			   function calls.  On success, the value of maxfd is guaranteed to be
			   greater or equal than -1.  We call select(maxfd + 1, ...), specially in
			   case of (maxfd == -1), we call select(0, ...), which is basically equal
			   to sleep. */

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

			switch (rc) {
			case -1:
				/* select error */
				break;
			case 0:
			default:
				/* timeout or readable/writable sockets */
				//printf("perform!\n");
				curl_multi_perform(multi_handle, &still_running);
				//printf("running: %d!\n", still_running);
				break;
			}
		} while (still_running);

		curl_multi_cleanup(multi_handle);

		/* always cleanup */
		curl_easy_cleanup(curl);

		/* then cleanup the formpost chain */
		curl_formfree(formpost);

		/* free slist */
		curl_slist_free_all(headerlist);
	}
	return 0;
}
struct FtpFile {
	const char *filename;
	FILE *stream;
};

size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
{
	struct FtpFile *out = (struct FtpFile *)stream;

	if (out && !out->stream) {
		out->stream = fopen(out->filename, "wb");//打开文件进行写入
		if (!out->stream)
			return -1;
	}
	return fwrite(buffer, size, nmemb, out->stream);
}

int downloadfile()
{
	CURL *curl;
	CURLcode res;

	struct FtpFile ftpfile = {
		//"C://SMGConfig.ini", //定义下载到本地的文件位置和路径
		szFileFrom,
		NULL
	};

	curl_global_init(CURL_GLOBAL_DEFAULT);
	curl = curl_easy_init();  //初始化一个curl指针

	if (curl)//curl对象存在的情况下执行的操作
	{ 
		//从下载到本地路径中截取文件名
		char szRemoteUrl[128] = "";
		std::string strFileUrl = szFileFrom;
		int pos = strFileUrl.rfind("\\\\");
		if (pos >= 0)
		{
			std::string strFileName = strFileUrl.substr(pos+2);
			sprintf(szRemoteUrl, "http://172.16.20.48/Config/%s", strFileName.c_str());
		}
		else
		{
			printf("找不到下载文件名!\n");
		}

		//设置远端地址
		//curl_easy_setopt(curl, CURLOPT_URL, "http://172.16.20.48/Config/SMGConfig.ini");
		curl_easy_setopt(curl, CURLOPT_URL, szRemoteUrl);

		//执行写入文件流操作
		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);//当有数据被写入,回调函数被调用,

		curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile); //设置结构体的指针传递给回调函数

		//启用时会汇报所有的信息,存放在STDERR或指定的CURLOPT_STDERR中

		curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);

		//curl_easy_setopt(curl, CURLOPT_USERPWD, "SUREN:SUREN");
		curl_easy_setopt(curl, CURLOPT_USERPWD, "ApiUserAdmin:123456");

		//写入文件
		res = curl_easy_perform(curl);

		//释放curl对象
		curl_easy_cleanup(curl);

		if (res != CURLE_OK)
		{
			std::cout << stderr << res << std::endl;
		}
	}

	if (ftpfile.stream)
	{
		//关闭文件流
		fclose(ftpfile.stream);
	}
	//释放全局curl对象
	curl_global_cleanup();

	return 0;
}

int main()
{
	//uploadfile();
	//downloadfile();
AGAIN:
	printf("uploadfile:1  downloadfile:2 exit:3 \n");
	std::cin >> nMethod;
	if (nMethod != -1)
	{
		if (nMethod == 1)
		{
			printf("本地上传文件路径(文件名需与远端文件名一致,如:C:\\\\SMGConfig.ini): \n");
			std::cin >> szFileFrom;
			uploadfile();
		}	
		else if (nMethod == 2)
		{
			printf("下载到本地路径(文件名需与远端文件名一致,如:C:\\\\SMGConfig.ini): \n");
			std::cin >> szFileFrom;
			downloadfile();
		}
		else if (nMethod == 3)
		{
			system("pause");
			return 0;
		}
		else
		{
			printf("请输入1 2或3!\n");
			goto AGAIN;
		}
	}
	goto AGAIN;
	system("pause");
	return 0;
}
upload.php
<?php 
	/*
    //获取文件后缀
    function fileext($filename)
	{
		return substr(strrchr($filename, '.'), 1);
	}
	*/
    
    $file = $_FILES['file']['name'];
    $file_tmp = $_FILES['file']['tmp_name'];
    if(isset($file))
    {
    	/*
    	//设置允许上传文件的类型
        $type=array("ini");
        //判断文件类型
        if(!in_array(strtolower(fileext($file)),$type))
        {
            header("HTTP/1.1 415 ERROR FILE TYPE");
            dump_to_file("$date $file error file type!");
            return;
        }
		*/
		
        $date = date('Y-m-d H:i:s');

        if (move_uploaded_file($file_tmp,"/mnt/flash/$file"))
        {
            dump_to_file("$date upload $file succeful!");
        }
    }
?>

 

libcurl 文件上传下载实例

licurl静态链接库:https://download.csdn.net/download/aixiaoql/12461024