2012-05-07 41 views
1

我必須在c中使用FTP協議和libcurl來傳輸文件。它工作正常,但我有一些問題。 1)如果傳輸開始,但在某個點,我斷開與網絡的連接,我的程序保留在libcurl函數中,速度爲0,我什麼也做不了。我試圖設置超時(CURLOPT_TIMEOUT),但這只是傳輸時間的超時。libcurl c,超時和成功傳輸

2)我有第二個問題,它與第一個問題有關,我怎麼知道trasfer是否成功完成?

我trasfer代碼:

struct FtpFile { 

    const char *filename; 
    FILE *stream; 
}; 
    long int size; 

static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream) 
{ 
    struct FtpFile *out=(struct FtpFile *)stream; 
    if(out && !out->stream) { 
    /* open file for writing */ 
    out->stream=fopen(out->filename, "ab"); 
    if(!out->stream) 
     return -1; /* failure, can't open file to write */ 
    } 
    return fwrite(buffer, size, nmemb, out->stream); 
} 

int sz; 

int main(void) 
{ 
    CURL *curl; 
    CURLcode res; 
    char prova; 

    struct stat statbuf; 
    FILE *stream; 

    /* apro il file per leggere la dimensione*/ 
    if ((stream = fopen("Pdf.pdf", "rb")) 
     == NULL) 
    { 
     fprintf(stderr, "Nessun file da aprire, il download partirà da zero.\n"); 
    } 
    else 
    { 
    /* Ricevo informazioni sul file */ 
    fstat(fileno(stream), &statbuf); 
    fclose(stream); 
    size = statbuf.st_size; 
    printf("Dimensione del file in byte: %ld\n", size); 
    } 

    struct FtpFile ftpfile={ 
    "Pdf.pdf", /* name to store the file as if succesful */ 
    NULL 
    }; 

    curl_global_init(CURL_GLOBAL_DEFAULT); 

    curl = curl_easy_init(); 
    if(curl) { 

    curl_easy_setopt(curl, CURLOPT_URL, "ftp://...."); 
    /* Define our callback to get called when there's data to be written */ 
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite); 
    /* Set a pointer to our struct to pass to the callback */ 
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile); 

    /* Switch on full protocol/debug output */ 
    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); 

    /*Pass a long as parameter. It contains the offset in number of bytes that you want the transfer to start from. 
    Set this option to 0 to make the transfer start from the beginning (effectively disabling resume). For FTP, set 
    this option to -1 to make the transfer start from the end of the target file (useful to continue an interrupted 
    upload). 

    When doing uploads with FTP, the resume position is where in the local/source file libcurl should try to resume 
    the upload from and it will then append the source file to the remote target file. */ 

    if(stream == NULL) 
    { 
     curl_easy_setopt(curl, CURLOPT_RESUME_FROM, 0); 
    } 
    else 
    { 
     curl_easy_setopt(curl, CURLOPT_RESUME_FROM, size); 
    } 

    /*Used to show file progress*/ 
    curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); 

    res = curl_easy_perform(curl); 

    /* always cleanup */ 
    curl_easy_cleanup(curl); 

    if(CURLE_OK != res) { 
     /* we failed */ 
     fprintf(stderr, "curl told us %d\n", res); 
    } 
    } 

    if(ftpfile.stream) 
    fclose(ftpfile.stream); /* close the local file */ 

    curl_global_cleanup(); 

    return 0; 
} 

回答

1

我最近回答了similar question了這一點。

1)這是設計。如果你想連接超時的,請嘗試使用這些來代替:

curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, dl_lowspeed_bytes);  
curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, dl_lowspeed_time); 

如果你的下載速率低於所需的閾值,可以檢查連接&採取任何行動,你認爲合適的。

NB:已在7.25.0:CURLOPT_TCP_KEEPALIVE, CURLOPT_TCP_KEEPIDLE
所以這些可能是你一個合適的選擇。


2)所示:

curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &dl_bytes_remaining); 
curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD, &dl_bytes_received); 
if (dl_bytes_remaining == dl_bytes_received) 
    printf("our work here is done ;)\n"); 
+0

謝謝你,它的工作! – phcaze