2012-05-07 7 views
1

私はFTPプロトコルとlibcurlを使ってファイルを転送しなければなりません。それは正常に動作しますが、私はいくつかの問題があります。libcurl c、タイムアウトと成功転送

1)転送が開始されたにもかかわらず、ある時点でネットワークから切断された場合、私のプログラムはlibcurl関数に残り、速度は0になり、何もできません。タイムアウト(CURLOPT_TIMEOUT)を設定しようとしましたが、転送時間のタイムアウトにすぎません。

2)私が持っている2番目の問題は、最初の問題にリンクされています。どのようにすれば、転送が正常に完了したかを知ることができますか?

マイ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

関連する問題