curl库ftp应用测试

标题:curl库实现ftp上传下载

注意:此代码只是支持FTP传输,不是sftp,并且需要先搭建好ftp服务器,如何搭建这里不说了。

#define FTP_COUNT “xxxxx:123456” 这是指定要登录的ftp服务器账号和密码.
#define FTP_SERVER “ftp://47.107.143.xx/upload/” 指定上传路径
#define FTP_SERVER_DOWN “ftp://47.107.143.xx/” 指定下载路径,这个需要看你自己搭建的ftp服务器ip多少了

直接上代码了

#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <curl/curl.h>
#include <sys/stat.h>

#define FTP_COUNT “xxxxx:123456”

/* parse headers for Content-Length */
size_t getcontentlengthfunc(void ptr, size_t size, size_t nmemb, void stream)
{
int r;
long len = 0;
/
_snscanf() is Win32 specific /
//r = _snscanf(ptr, size * nmemb, “Content-Length: %ld\n”, &len);
r = sscanf((const char
)ptr, “Content-Length: %ld\n”, &len);
if ® /
Microsoft: we don’t read the specs */
*((long *) stream) = len;
return size * nmemb;
}

/* discard downloaded data */
size_t discardfunc(void *ptr, size_t size, size_t nmemb, void *stream)
{
return size * nmemb;
}
//write data to upload
size_t writefunc(void ptr, size_t size, size_t nmemb, void stream)
{
return fwrite(ptr, size, nmemb, (FILE
)stream);
}
/
read data to upload */
size_t readfunc(void *ptr, size_t size, size_t nmemb, void *stream)
{
FILE f = (FILE)stream;
size_t n;
if (ferror(f))
return CURL_READFUNC_ABORT;
n = fread(ptr, size, nmemb, f) * size;
return n;
}
//这是显示上传下载进度回调函数: ultotal:本来应该是获取需要上传文件总大小的,但不知道为什么是0,所以我测试用一个固定字节大小文件,以此来打印上传速率,否则无法统计速率,下载dltotal,d 这两个参数是没问题的
int my_progress_func(char progress_data,double t, / dltotal /double d, / dlnow */double ultotal,double ulnow)
{
double speed;
CURL *easy_handle=(CURL *)progress_data;

ultotal = 16463060.0;
//printf("#######  %f %f #####\n",ultotal,ulnow);
//if(t !=0)
//	curl_easy_getinfo(easy_handle, CURLINFO_SPEED_DOWNLOAD, &speed); // curl_get_info必须在curl_easy_perform之后调用
//else
	curl_easy_getinfo(easy_handle, CURLINFO_SPEED_UPLOAD, &speed); // curl_get_info必须在curl_easy_perform之后调用

if(((ulnow !=0) && (ulnow == ultotal)) ){
	if(speed > 1024*1024*1024){
		speed /= 1024*1024*1024;
		ulnow /= 1024*1024*1024;
		ultotal /= 1024*1024*1024;
		printf("speed: %0.3lf G/s\n",speed);
		printf("-----> %gG / %gG (%g %%)\n",ultotal,ulnow, ulnow*100.0/ultotal);  
	}else if(speed >1024*1024){
		speed /= 1024*1024;
		ulnow /= 1024*1024;
		ultotal /= 1024*1024;
		printf("speed: %0.3lf M/s\n",speed);
		printf("-----> %g M / %g M (%g %%)\n",ultotal,ulnow, ulnow*100.0/ultotal);  
	}
	else if(speed >1024){
		speed /= 1024;
		ulnow /= 1024;
		ultotal /= 1024;
		printf("speed: %0.3lf kb/s\n",speed);
		printf("-----> %g kb / %g kb (%g %%)\n",ultotal,ulnow, ulnow*100.0/ultotal);  
	}else{
		printf("speed: %0.3lf b/s\n",speed);
		printf("-----> %g  / %g  (%g %%)\n",ultotal,ulnow, ulnow*100.0/ultotal);  
	}
}

if(((d!=0) && (d == t)) ){
	if(speed > 1024*1024*1024){
		speed /= 1024*1024*1024;
		d /= 1024*1024*1024;
		t /= 1024*1024*1024;
		printf("speed: %0.3lf G/s\n",speed);
		printf("-----> %gG / %gG (%g %%)\n",d, t, d*100.0/t);  
	}else if(speed >1024*1024){
		speed /= 1024*1024;
		d /= 1024*1024;
		t /= 1024*1024;
		printf("speed: %0.3lf M/s\n",speed);
		printf("-----> %gMb / %gMb (%g %%)\n",d, t, d*100.0/t);  
	}
	else if(speed >1024){
		speed /= 1024;
		d /= 1024;
		t /= 1024;
		printf("speed: %0.3lf kb/s\n",speed);
		printf("-----> %gkb / %gkb (%g %%)\n",d, t, d*100.0/t);  
	}else{
		printf("speed: %0.3lf b/s\n",speed);
		printf("-----> %g / %g (%g %%)\n",d, t, d*100.0/t);  
	}
}
return 0;  

}

static xferinfo(void *p,curl_off_t dltotal,curl_off_t dlnow,curl_off_t ultotal,curl_off_t ulnow)
{
double speed;
CURL *curlhandle = (CURL *)p;

curl_easy_getinfo(curlhandle, CURLINFO_SPEED_UPLOAD, &speed);           // curl_get_info必须在curl_easy_perform之后调用
fprintf(stderr,"UP:%" CURL_FORMAT_CURL_OFF_T "  of %" CURL_FORMAT_CURL_OFF_T
       " DOWN:%" CURL_FORMAT_CURL_OFF_T " of %" CURL_FORMAT_CURL_OFF_T
       "\r\n",ulnow,ultotal,dlnow,dltotal);

return 0;

}

int upload(CURL *curlhandle, const char * remotepath, const char * localpath, long timeout, long tries)
{
FILE *f,*fileptr;
long uploaded_len = 0;
CURLcode r = CURLE_GOT_NOTHING;
int c;

f = fopen(localpath, "rb");  
if (f == NULL) {  
	perror(NULL);  
	return 0;  
}  
curl_easy_setopt(curlhandle, CURLOPT_UPLOAD, 1L);  
curl_easy_setopt(curlhandle, CURLOPT_URL, remotepath);  
curl_easy_setopt(curlhandle, CURLOPT_USERPWD,FTP_COUNT);     
if (timeout)  
	curl_easy_setopt(curlhandle, CURLOPT_FTP_RESPONSE_TIMEOUT, timeout);  

curl_easy_setopt(curlhandle, CURLOPT_HEADERFUNCTION, getcontentlengthfunc);  
curl_easy_setopt(curlhandle, CURLOPT_HEADERDATA, &uploaded_len);  
curl_easy_setopt(curlhandle, CURLOPT_WRITEFUNCTION, discardfunc);  
curl_easy_setopt(curlhandle, CURLOPT_READFUNCTION, readfunc);  
curl_easy_setopt(curlhandle, CURLOPT_READDATA, f);  
curl_easy_setopt(curlhandle, CURLOPT_FTPPORT, "-"); /* disable passive mode */  
curl_easy_setopt(curlhandle, CURLOPT_FTP_CREATE_MISSING_DIRS, 1L);  
curl_easy_setopt(curlhandle, CURLOPT_VERBOSE, 1L);  

#if 1
curl_easy_setopt(curlhandle, CURLOPT_NOPROGRESS, 0L);
curl_easy_setopt(curlhandle, CURLOPT_PROGRESSFUNCTION, my_progress_func);
curl_easy_setopt(curlhandle, CURLOPT_PROGRESSDATA,curlhandle);
#else
curl_easy_setopt(curlhandle, CURLOPT_NOPROGRESS, 0L);
curl_easy_setopt(curlhandle, CURLOPT_XFERINFOFUNCTION,xferinfo);
curl_easy_setopt(curlhandle, CURLOPT_XFERINFODATA,curlhandle);
#endif
for (c = 0; (r != CURLE_OK) && (c < tries); c++) {
/* are we resuming? /
if © { /
yes /
/
determine the length of the file already written /
/

* With NOBODY and NOHEADER, libcurl will issue a SIZE
* command, but the only way to retrieve the result is
* to parse the returned Content-Length header. Thus,
* getcontentlengthfunc(). We need discardfunc() above
* because HEADER will dump the headers to stdout
* without it.
/
curl_easy_setopt(curlhandle, CURLOPT_NOBODY, 1L);
curl_easy_setopt(curlhandle, CURLOPT_HEADER, 1L);
r = curl_easy_perform(curlhandle);
if (r != CURLE_OK)
continue;
curl_easy_setopt(curlhandle, CURLOPT_NOBODY, 0L);
curl_easy_setopt(curlhandle, CURLOPT_HEADER, 0L);
fseek(f, uploaded_len, SEEK_SET);
curl_easy_setopt(curlhandle, CURLOPT_APPEND, 1L);
}
else { /
no */
curl_easy_setopt(curlhandle, CURLOPT_APPEND, 0L);
}

	fileptr = fopen("dump","wb");
	if(fileptr == NULL){
		return 0;
	}
	curl_easy_setopt(curlhandle,CURLOPT_STDERR,fileptr);
	r = curl_easy_perform(curlhandle);  
}  
fclose(f);  
fclose(fileptr);

if (r == CURLE_OK)  
	return 1;  
else {  
	fprintf(stderr, "%s\n", curl_easy_strerror(r));  
	return 0;  
}  

}

// 下载
int download(CURL *curlhandle, const char * remotepath, const char * localpath, long timeout, long tries)
{
FILE *f;
curl_off_t local_file_len = -1 ;
long filesize =0 ;
CURLcode r = CURLE_GOT_NOTHING;
struct stat file_info;
int use_resume = 0;
char progress_data = " ";

//获取本地文件大小信息  
if(stat(localpath, &file_info) == 0)  
{  
	local_file_len = file_info.st_size;   
	use_resume = 1;  
}  
//追加方式打开文件,实现断点续传  
f = fopen(localpath, "ab+");  
if (f == NULL) {  
	perror("fopen");  
	return 0;  
}  
curl_easy_setopt(curlhandle, CURLOPT_URL, remotepath);  
curl_easy_setopt(curlhandle, CURLOPT_USERPWD, FTP_COUNT);     
//连接超时设置  
curl_easy_setopt(curlhandle, CURLOPT_CONNECTTIMEOUT, timeout);  
//设置头处理函数  
curl_easy_setopt(curlhandle, CURLOPT_HEADERFUNCTION, getcontentlengthfunc);  
curl_easy_setopt(curlhandle, CURLOPT_HEADERDATA, &filesize);  
// 设置断点续传  
curl_easy_setopt(curlhandle, CURLOPT_RESUME_FROM_LARGE, use_resume?local_file_len:0);  
curl_easy_setopt(curlhandle, CURLOPT_WRITEFUNCTION, writefunc);  
curl_easy_setopt(curlhandle, CURLOPT_WRITEDATA, f);  
curl_easy_setopt(curlhandle, CURLOPT_NOPROGRESS, 1L);  
curl_easy_setopt(curlhandle, CURLOPT_VERBOSE, 1L);  

curl_easy_setopt(curlhandle, CURLOPT_NOPROGRESS, 0L);
curl_easy_setopt(curlhandle, CURLOPT_PROGRESSFUNCTION, my_progress_func);  
curl_easy_setopt(curlhandle, CURLOPT_PROGRESSDATA,curlhandle);
//curl_easy_setopt(curlhandle, CURLOPT_XFERINFOFUNCTION, progress_callback);

r = curl_easy_perform(curlhandle);  
fclose(f);  
if (r == CURLE_OK)  
	return 1;  
else {  
	fprintf(stderr, "%s\n", curl_easy_strerror(r));  
	return 0;  
}  

}

#define FTP_SERVER “ftp://47.107.143.xxx/upload/”
#define FTP_SERVER_DOWN “ftp://47.107.143.xxx/”

int main(int c, char **argv)
{

if(c != 3){
	printf("%s get or put  local_file\n",argv[0]);
	exit(1);
}

char remote_path[128];
char local_path[128];
char remote_downpath[128];


snprintf(remote_path,sizeof(remote_path),"%s%s",FTP_SERVER,argv[2]);
snprintf(remote_downpath,sizeof(remote_downpath),"%s%s",FTP_SERVER_DOWN,argv[2]);
//snprintf(remote_path,sizeof(remote_path),"%s%s",FTP_SERVER,argv[2]);
//snprintf(remote_downpath,sizeof(remote_downpath),"%sdownload/%s",FTP_SERVER,argv[2]);
snprintf(local_path,sizeof(local_path),"./%s",argv[2]);

CURL *curlhandle = NULL;  
CURL *curldwn = NULL;  
curl_global_init(CURL_GLOBAL_ALL);  
curlhandle = curl_easy_init();  
curldwn = curl_easy_init();  

if(strcmp(argv[1],"put")==0){
	upload(curlhandle,remote_path,local_path, 1, 3);  
}else{
	download(curldwn,remote_downpath,local_path,1, 3);  
}

curl_easy_cleanup(curlhandle);  
curl_easy_cleanup(curldwn);  
curl_global_cleanup();  
return 0;  

}

编译以后加入生成 ftp_bin
执行命令: ./ftp_bin put file 上传file ./ftp_bin get file 下载file

编译注意需要链接库: gcc -o ftp_bin ftp_bin.c -lcurl

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值