Libcurl的初步實現tfp上傳下載功能
該學習筆記的目標是利用libcurl實現ftp文件上傳和下載功能
一、Libcurlde的簡單介紹
Libcurl是一個免費的而且易於使用的利用url進行文件傳輸的庫。
, libcurl當前支持DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP, IMAPS, LDAP,LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, Telnet and TFTP協議。libcurl相同支持HTTPS證書授權,HTTP POST, HTTP PUT, FTP 上傳, HTTP基本表單上傳。代理,cookies,和用戶認證。
Libcurl是一個輕量級的庫,編譯後可以執行到多種平臺,包含:Solaris, NetBSD, FreeBSD, OpenBSD, Darwin, HPUX, IRIX, AIX, Tru64,Linux, UnixWare, HURD, Windows, Amiga, OS/2, BeOs, Mac OS X, Ultrix, QNX,OpenVMS, RISC OS, Novell NetWare, DOS 等
二、libcurl的接口
Libcurl分為簡單和復雜的接口。簡單的接口是一個同步的,高效的。高速的,這樣的借口主要用於文件傳輸。大量的應用程序都使用這樣的方式。
而復雜的姐姐偶是一個異步的,在這裏不做過多研究
三、libcurl簡單的接口工作流程
1、使用libcurl中的curl_easy_init()來初始化一個簡單的文件傳輸會話而且獲取到一個handle
2、通過使用curl_easy_setopt()來設置全部的選項參數,在這些參數中最重要的就是URL,同一時候你也極有可能須要設置一些回調函數。這些回調函數將會在條件符合的情況下被調用。
3、當上面的工作都做完了的時候,就能夠使用curl_easy_perform()通知libcurl進行文件傳輸了,該函數在整個傳輸過程完畢或者失敗的時候才會返回一個值。
4、當你運行了第3步之後,你能夠使用curl_easy_getinfo()來獲取傳輸的信息
5、最後。你相同能夠使用curl_easy_cleanup()來結束本次文件會話
以下針對這五個步驟。編寫一個實例進行測試
四、部分功能函數的介紹
1、CURL *curl_easy_init( );
該函數必須首先調用。將會返回一個CURL*類型的handle.而且該函數將會和curl_easy_cleanup()一起配合使用。
增加初始化出錯的話。該函數將會返回一個NULL。
2、void curl_easy_cleanup(CURL *handle)
該函數一定是最後被調用的,他的參數應該是curl_easy_init的返回值;
3、CURLcode curl_easy_setopt(CURL*handle, CURLoption option, parameter);
該函數從名字上看就知道是設置一些參數的。通過設置不同的參數。將會改變libcurl的功能作用,這個須要細致閱讀指導文檔,一旦設置方式不恰當。導致的錯誤將是致命的。
具體參數的使用方式在這個網址上描寫敘述的非常具體
http://curl.haxx.se/libcurl/c/curl_easy_setopt.html
4、CURLcode curl_easy_perform(CURL * easy_handle);
像我們剛才提到的那樣,這個函數應該是在init和setopt之後使用的,這個函數一旦運行。將會通知libcurl運行我們之前設置的全部方法,值得註意的是,當一個handle被增加到一個multi handle中之後,該參數handle將不能被函數perform調用
五、實例演示
1、以下來看一個簡單的實例:
#include<stdio.h> #include<curl/curl.h> int main(int argc,char** argv) { CURL *pCurlHandle = NULL; CURLcode errorCode = 0; /*1. 初始化一個pCurlHandle*/ pCurlHandle = curl_easy_init(); if( pCurlHandle ) { /*2. 設置pCurlHandle的URL*/ curl_easy_setopt( pCurlHandle,CURLOPT_URL, "http://blog.csdn.net/jxnu_xiaobing" ); /*3. 由於上述網址已被重定向了,所以設置為CURLOPT_FOLLOWLOCATION*/ curl_easy_setopt( pCurlHandle,CURLOPT_FOLLOWLOCATION, 1L ); /*4. 開始運行上述opt*/ errorCode = curl_easy_perform(pCurlHandle ); if( errorCode != CURLE_OK ) { printf("curl_easy_perform() failed \n "); } } else { printf(" curl_easy_init() failed \n "); } /*5. 最後關閉pCurlHandle*/ curl_easy_cleanup( pCurlHandle ); return 0; }
2、上述的樣例比較簡單就是一個訪問網頁的樣例,以下繼續學習一個ftp上傳的樣例
#include<stdio.h> #include<string.h> #include<curl/curl.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> #include<errno.h> #include<unistd.h> #defineLOCAL_FILE "/tmp/xiaobing.txt" #defineREMOTE_URL "ftp://172.30.26.247:21/xiaobing.txt" static size_tread_callback(void *ptr, size_t size, size_t nmemb, void *stream) { curl_off_t nread; /* in real-world cases, this would probablyget this data differently as this fread() stuff is exactly what thelibrary already would do by default internally */ size_t retcode = fread(ptr, size, nmemb,(FILE*)stream); nread = (curl_off_t)retcode; fprintf(stderr, "*** We read %"CURL_FORMAT_CURL_OFF_T " bytes from file\n",nread); return retcode; } int main(int argc,char **argv) { CURL *pCurlhandle; CURLcode res; FILE *hd_src; struct stat file_info; curl_off_t fsize; /*1. 獲取待上傳文件的大小 */ if(stat(LOCAL_FILE, &file_info)) { printf("Couldnt open ‘%s‘: %s\n",LOCAL_FILE, strerror(errno)); return 1; } fsize = (curl_off_t)file_info.st_size; printf("Local file size: %"CURL_FORMAT_CURL_OFF_T " bytes.\n", fsize); /*2. 獲取待上傳文件的描寫敘述符 */ hd_src = fopen(LOCAL_FILE, "rb"); /*3. 初始化全部可能的調用*/ curl_global_init(CURL_GLOBAL_ALL); /*4. 創建一個curlhandle*/ pCurlhandle = curl_easy_init(); if(curl) { /*5.設置一個回調函數 */ curl_easy_setopt(pCurlhandle, CURLOPT_READFUNCTION, read_callback); /*6.使能上傳標誌位 */ curl_easy_setopt(pCurlhandle, CURLOPT_UPLOAD, 1L); /*7.指定ftpserver的url */ curl_easy_setopt(pCurlhandle,CURLOPT_URL, REMOTE_URL); /*8.指定須要上傳的文件 */ curl_easy_setopt(pCurlhandle, CURLOPT_READDATA, hd_src); /*9.設置待上傳文件的大小。這個大小是上面獲取到的註意:當參數 為CURLOPT_INFILESIZE_LARGE的時候。size類型應該是curl_off_t的。 當參數為CURLOPT_INFILESIZE的時候size應該是long類型的*/ curl_easy_setopt(pCurlhandle, CURLOPT_INFILESIZE_LARGE, (curl_off_t)fsize); /*10. 開始運行我們上述設定的方法*/ res= curl_easy_perform(pCurlhandle); /*11. 檢查是否運行成功 */ if(res != CURLE_OK) fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); /*12. 關閉pCurlhandle*/ curl_easy_cleanup(pCurlhandle); } fclose(hd_src); /* close the local file */ /*13. 清除全部可能的調用*/ curl_global_cleanup(); return 0; }
上述程序就行實現ftp上傳文件
3、最後來看一個tfp下載的實例:
/************************************************************************************* * * 文件名稱: TfpcurlDownload.c * * 功能: curl測試程序 * * 作者: http://blog.csdn.net/King_BingGe * * 創建時間: 2014年09月29號 * * 最後改動時間: 2014年09月29號 * * 具體: 無 * **************************************************************************************/ #include <stdio.h> #include <string.h> #include <curl/curl.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <errno.h> #include <unistd.h> #define REMOTE_URL "ftp://172.30.26.247:21/xiao.txt" typedef struct Ftpfile { const char *filename; FILE *stream; }Cftpfile; static size_t write_callback(void *ptr, size_t size, size_t nmemb, void *stream) { Cftpfile *out = (Cftpfile*)stream; if( out && !out->stream ) { out->stream = fopen(out->filename, "wb"); if(!out->stream) { printf("write_callback failed \n "); return -1; } } return fwrite(ptr, size, nmemb, out->stream); } int main(int argc, char **argv) { CURL *pCurlhandle; CURLcode res; curl_off_t fsize; Cftpfile ftpfile = { "/tmp/xiaoxiao.txt" , NULL }; /*3. 初始化全部可能的調用*/ curl_global_init(CURL_GLOBAL_ALL); /*4. 創建一個curlhandle*/ pCurlhandle = curl_easy_init(); if(pCurlhandle) { /*5. 設置一個回調函數 */ curl_easy_setopt(pCurlhandle, CURLOPT_WRITEFUNCTION, write_callback ); /*7. 指定ftpserver的url */ curl_easy_setopt(pCurlhandle,CURLOPT_URL, REMOTE_URL); /*8. 指定須要上傳的文件 */ curl_easy_setopt(pCurlhandle, CURLOPT_USERPWD, "cdn_ftp:123456"); /*9. 指定須要上傳的文件 */ curl_easy_setopt(pCurlhandle, CURLOPT_WRITEDATA, &ftpfile ); /*10. 設置待下載文件的大小,這個大小是上面獲取到的註意:當參數 為CURLOPT_INFILESIZE_LARGE的時候,size類型應該是curl_off_t的, 當參數為CURLOPT_INFILESIZE的時候size應該是long類型的*/ curl_easy_setopt(pCurlhandle, CURLOPT_INFILESIZE_LARGE, (curl_off_t)fsize); /*11. 開始運行我們上述設定的方法 */ res = curl_easy_perform(pCurlhandle); /*12. 檢查是否運行成功 */ if(res != CURLE_OK) fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); /*13. 關閉pCurlhandle*/ curl_easy_cleanup(pCurlhandle); } else { printf("curl_easy_init failed \n "); } /*14. 清除全部可能的調用*/ curl_global_cleanup(); return 0; }
Libcurl的初步實現tfp上傳下載功能