curl 实现 https、ftp下载文件 代码

cURL 是一个网络数据传输项目,通常说 cURL 是指 curl 命令行工具,它支持 DICT、FILE、FTP、FTPS、Gopher、HTTP、HTTPS、IMAP、IMAPS、LDAP、LDAPS、POP3、POP3S、RTMP、RTSP、SCP、SFTP、SMB、SMBS、SMTP、SMTPS、Telnet 与 TFTP 等协议,而 curl 的底层使用的是 libcurl 库,libcurl 与 curl 组成了 cURL 项目。

curl 源码下载 https://curl.se/download.html

下载之后三步:
1.解压
2.进入目录:./configure --with-gnutls (打开tls)
3.make
4.make install

测试命令:

curl -v https://www.baidu.com
curl -V

命令没问题的话我们源码编译安装成功,下面就可以写代码实现了。

https实现下载功能:

#include 
#include 
#include 
#include 

static int download_progress;

struct progress {
   char *private;
   size_t size;
};

typedef struct HTTP_OPT
{
	char url[128];		/*url of https*/
//	char *user_key;		// username:password
	char *file;		/*filepath*/
}HTTP_OPT;


static size_t callback_download_response(void *contents, size_t size, size_t nmemb, void *userp)
{
	size_t realsize = size * nmemb;
	int count = 0;

FILE* fp = (FILE *)userp;
if (!fp) {
	/* out of memory! */
	fprintf(stderr ,"not file to save download data .\n");
	return 0;
}

if(contents && realsize > 0 ) {
	count = fwrite(contents, 1, realsize, fp);
	if (count != realsize) {
		fprintf(stderr, "write file failed, size:%d != write_count:%d\n", realsize, count);
		fflush(fp);
		return 0;
	}
}
fflush(fp);

return realsize;
}

static size_t progress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)
{
	int progress = 0;
	progress = (int)(dlnow / dltotal * 100);
	fprintf(stderr, "download progress = %d / 100", progress);
	download_progress = progress;
 
   return 0;
}

int get_download_progress()
{
	return download_progress;
}

CURL *curl_init()          //curl初始化
{
	download_progress = 0;
	curl_global_init(CURL_GLOBAL_DEFAULT); 
	CURL *curl = curl_easy_init();
	if(NULL == curl)
	{
		fprintf(stderr, "Init curl failed.\n");
		exit(1);
	}
	return curl;
}

void curl_deinit(CURL *curl)  //退出curl
{
	curl_easy_cleanup(curl);
	curl_global_cleanup(); 
}

int https_download(const HTTP_OPT http_option)
{

CURL *curl;
struct progress data;

FILE *fp = fopen(http_option.file, "w");
if(NULL == fp)
{
	fprintf(stderr, "Open file failed at %s:%d\n", __FILE__, __LINE__);
	return -1;
}

curl = curl_init();

if (curl) {
	CURLcode res;

	curl_easy_setopt(curl, CURLOPT_POST, 0);
	curl_easy_setopt(curl, CURLOPT_URL, http_option.url);

	//跳过证书校验
	curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
	curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);

	//6秒未达到30字节会退出
	curl_easy_setopt(curl,CURLOPT_LOW_SPEED_TIME,6L);
	curl_easy_setopt(curl,CURLOPT_LOW_SPEED_LIMIT,30L);

	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback_download_response);
	curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);

	//获得进度条
//	curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &data);
//	curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_callback);  
//	curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);

	res = curl_easy_perform(curl);

	if (res != CURLE_OK) {
		fprintf(stderr, "curl_easy_perform() failed: %s\n",
			curl_easy_strerror(res));
		//res = curl_easy_getinfo(curl, CURLINFO_HTTP_CODE);
		res = -1;
	}

	fclose(fp);
	curl_deinit(curl);
	return 0;

}
return -1;
}

int download_https(char* addr, char* refile, char* lofile)
{
	HTTP_OPT http_opt;
	sprintf(http_opt.url, "%s%s", addr, refile);
	fprintf(stderr, "http_opt.url = %s\n",http_opt.url);
	http_opt.file = lofile;
	if (https_download(http_opt) != 0) {
		fprintf(stderr, "Download failed.\n");
		return -1;
	} else {
		fprintf(stderr, "Download success.\n");
		return 0;
	}
}

int main()
{
	download_https("https://filesamples.com","/samples/image/bmp/sample_640×426.bmp", "sample_640×426.bmp" );
}

ftp实现下载功能

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 


typedef enum FTP_STATE
{
	FTP_UPLOAD_SUCCESS,
	FTP_UPLOAD_FAILED,
	FTP_DOWNLOAD_SUCCESS,
	FTP_DOWNLOAD_FAILED 
}FTP_STATE;
 
typedef struct FTP_OPT
{
	//char *url;		/*url of ftp*/
	char url[80];		/*url of ftp*/
	char *user_key;		/*username:password*/
	char *file;		/*filepath*/
}FTP_OPT;

char _ip_addr[16];//远程主机IP地址

static int get_file_size(FILE *file) //获取文件大小
{
	int size = 0;
	fseek(file, 0L, SEEK_END);
	size = ftell(file);
	fseek(file, 0L, SEEK_SET);
	return size;
}

static int getipaddr(const char* _host)
{
    memset(_ip_addr, 0, 16);
    /*通过域名得到相应的ip地址*/
    struct hostent *host = gethostbyname(_host);//此函数将会访问DNS服务器
    if (!host) {
        fprintf(stderr, "找不到IP地址,请检查DNS服务器!");
        return(-1);
    }

    for (int i = 0; host->h_addr_list[i]; i++) {
        strcpy(_ip_addr, inet_ntoa( * (struct in_addr*) host->h_addr_list[i]));
        break;
    }

if (strlen(_ip_addr) == 0) {
    fprintf(stderr, "错误: 无法获取到远程服务器的IP地址, 请检查下载地址的有效性\n");
    return(-1);
}
return 0;
}

CURL *curl_init()          //curl初始化
{
	curl_global_init(CURL_GLOBAL_DEFAULT); 
	CURL *curl = curl_easy_init();
	if(NULL == curl)
	{
		fprintf(stderr, "Init curl failed.\n");
		exit(1);
	}
	return curl;
}
 
void curl_set_upload_opt(CURL *curl, const char *url, const char *user_key, FILE *file) //设置上传配置参数
{
	curl_easy_setopt(curl, CURLOPT_URL, url);
	curl_easy_setopt(curl, CURLOPT_USERPWD, user_key);
	curl_easy_setopt(curl, CURLOPT_READDATA, file);	
	curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
	curl_easy_setopt(curl, CURLOPT_INFILESIZE, get_file_size(file));
	curl_easy_setopt(curl, CURLOPT_FTP_CREATE_MISSING_DIRS, 1);
//	curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
}
 
void curl_set_download_opt(CURL *curl, const char *url, const char *user_key, FILE *file) //设置下载配置参数
{
	curl_easy_setopt(curl, CURLOPT_URL, url);
	curl_easy_setopt(curl, CURLOPT_USERPWD, user_key);
	curl_easy_setopt(curl, CURLOPT_WRITEDATA, file);
//	curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
}
 
void curl_exit(CURL *curl)  //退出curl
{
	curl_easy_cleanup(curl);
	curl_global_cleanup(); 
}
 
CURLcode curl_perform(CURL *curl) //执行curl
{
	CURLcode ret = curl_easy_perform(curl);
	if(ret != 0)
	{
		fprintf(stderr, "Perform curl failed.\n");
		curl_exit(curl);
		exit(1);
	}
	return ret;
}
 
 
FTP_STATE ftp_upload(const FTP_OPT ftp_option) //ftp上传文件
{
	FTP_STATE state;
	CURL *curl;;
	FILE *fp = fopen(ftp_option.file, "r");
	if(NULL == fp)
	{
		fprintf(stderr, "Open file failed at %s:%d\n", __FILE__, __LINE__);
		return FTP_UPLOAD_FAILED;
	}

curl = curl_init();
curl_set_upload_opt(curl, ftp_option.url, ftp_option.user_key, fp);
if(CURLE_OK == curl_perform(curl))
	state = FTP_UPLOAD_SUCCESS;
else
	state = FTP_UPLOAD_FAILED;

curl_exit(curl);
fclose(fp);
return state;
}
 
FTP_STATE ftp_download(const FTP_OPT ftp_option) // ftp下载文件
{
	FTP_STATE state;
	CURL *curl;
	FILE *fp = fopen(ftp_option.file, "w");
	if(NULL == fp)
	{
		fprintf(stderr, "Open file failed at %s:%d\n", __FILE__, __LINE__);
		return FTP_UPLOAD_FAILED;
	}

curl = curl_init();
curl_set_download_opt(curl, ftp_option.url, ftp_option.user_key, fp);
if(CURLE_OK == curl_perform(curl))
	state = FTP_DOWNLOAD_SUCCESS;
else
	state = FTP_DOWNLOAD_FAILED;

curl_exit(curl);
fclose(fp);
return state;
}

int download_ftp(char* addr, char* refile, char* lofile)
{

if(getipaddr(addr) < 0)
	return -1;

FTP_OPT ftp_opt;
sprintf(ftp_opt.url, "ftp://%s%s", _ip_addr, refile);
fprintf(stderr, "ftp_opt.url = %s\n",ftp_opt.url);
ftp_opt.file = lofile;	//指下载到本地文件名
ftp_opt.user_key = "anonymous:";
if(FTP_DOWNLOAD_SUCCESS == ftp_download(ftp_opt))
	fprintf(stderr, "Download success.\n");
else
	fprintf(stderr, "Download failed.\n");

return 0;
}

int main()
{
	download_ftp("192.168.5.3","/samples/image/bmp/sample_640×426.bmp", "sample_640×426.bmp" );
}

你可能感兴趣的:(C语言,https,ftp,curl,linux,c语言)