2012-02-23 11 views
8

मैं एफ़टीपी का उपयोग कर फ़ाइल डाउनलोड करने की कोशिश कर रहा हूं, और कनेक्शन के समाप्त होने के बीच में इसे फिर से शुरू करना चाहिए जहां से यह रुक गया था। मेरी समस्या यह है कि निम्न कोड स्निपेट का उपयोग करके मैं डाउनलोड जारी रखने में सक्षम हूं अगर मैं कनेक्शन बंद करता हूं और फिर इसे कनेक्ट करता हूं, लेकिन अगर मैं सर्वर साइट पर ऐसा कर रहा हूं तो मैं डाउनलोड फिर से शुरू करने में सक्षम नहीं हूं, और प्रोग्राम infinites स्थिति में चला जाता है।सीएल में कर्ल का उपयोग करके एफ़टीपी के माध्यम से फ़ाइल डाउनलोड कैसे शुरू करें?

#include <stdio.h> 

#include <curl/curl.h> 

/* 
* This is an example showing how to get a single file from an FTP server. 
* It delays the actual destination file creation until the first write 
* callback so that it won't create an empty file in case the remote file 
* doesn't exist or something else fails. 
*/ 

struct FtpFile { 
    const char *filename; 
    FILE *stream; 
}; 

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, "wb"); 
    if(!out->stream) 
     return -1; /* failure, can't open file to write */ 
    } 
    return fwrite(buffer, size, nmemb, out->stream); 
} 


int main(void) 
{ 
    CURL *curl; 
    CURLcode res; 
    struct FtpFile ftpfile={ 
    "dev.zip", /* name to store the file as if succesful */ 
    NULL 
    }; 

    curl_global_init(CURL_GLOBAL_DEFAULT); 

    curl = curl_easy_init(); 
    if(curl) { 
    /* 
    * You better replace the URL with one that works! 
    */ 
    curl_easy_setopt(curl, CURLOPT_URL, 
        "ftp://root:[email protected]/dev.zip"); 
    /* 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); 

    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; 
} 

क्या कोई मुझे बता सकता है कि रिमोट साइट द्वारा कनेक्शन बंद होने पर मैं फिर से डाउनलोड कैसे कर सकता हूं। किसी भी मदद की सराहना की जाएगी

धन्यवाद,

युवी

+0

क्या कुछ चीज http की 'AddRange' ftp में है? –

+0

हाँ यह वहां है लेकिन मेरी समस्या यह है कि कनेक्शन बंद होने पर मैं त्रुटि पकड़ने में सक्षम नहीं हूं, और अधिक जानने के लिए आप इसे यहां देख सकते हैं http://curl.haxx.se/libcurl/c/ftpuploadresume.html – Yuvi

उत्तर

2

जरूरत महसूस की, अपने लिखने कार्य करने के लिए ftpfile struct करने के लिए एक varaible जोड़े appeand और libcurl बता के अंत से डाउनलोड फिर से शुरू करने के लिए गंतव्य फ़ाइल बाइट की संख्या को CURLOPT_RESUME_FROM की स्थापना द्वारा पहले से ही डाउनलोड:

struct FtpFile 
{ 
    const char *pcInfFil; 
    FILE *pFd; 
    int iAppend; 
}; 

मुख्य में, यदि आप फिर से शुरू करना चाहते हैं:

012,
curl_easy_setopt(curl, CURLOPT_RESUME_FROM , numberOfBytesToSkip); 

आप फ़ाइल पहले से ही मौजूद नहीं है, या यह एक फिर से शुरू डाउनलोड लेकिन एक नए डाउनलोड नहीं है, CURLOPT_RESUME_FROM 0.

वापस करने के लिए सेट करने के लिए my_fwrite में सुनिश्चित हो:

out->stream=fopen(out->filename, out->iAppend ? "ab":"wb"); 

पुनश्च अगर तुम कहाँ फिर से शुरू करने के लिए एक लंबे फ़ाइल (2GB) से भी बड़ा है की जरूरत है, CURLOPT_RESUME_FROM_LARGE और CURL_OFF_T_C()

पर गौर कैसे पता करने के लिए के बारे में अतिरिक्त जानकारी के लिए अनुरोध टिप्पणी के जवाब में एक स्थानान्तरण विफल जब:

आप के बाद फोन कर्ल आसान प्रदर्शन कॉल:

CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...); 

कर्ल संदर्भ से प्राप्त करें:

CURLINFO_HEADER_SIZE 
CURLINFO_CONTENT_LENGTH_DOWNLOAD 

उन्हें एक साथ जोड़ें और सुनिश्चित करें कि वे ई बनाने योग्य

CURLINFO_SIZE_DOWNLOAD 

यदि संदर्भ को दोबारा सुधारने की कोशिश न करें।

और कर्ल के नवीनतम संस्करण का उपयोग करना सुनिश्चित करें, इसे डाउनलोड करने वाले FTP सर्वर से सुनवाई के 60 सेकंड के बाद टाइमआउट होना चाहिए।

+0

धन्यवाद उत्तर के लिए, लेकिन मुझे कैसे पता चलेगा कि रिमोट साइट द्वारा कनेक्शन बंद है, यह नमूना प्रोग्राम स्थिति में नहीं जाता है, यह अनंत स्थिति में रहता है ... – Yuvi

0

आप प्रति-हैंडल आधार पर कनेक्ट टाइमआउट और अधिकतम निष्पादन समय निर्दिष्ट करने के लिए CURLOPT_CONNECTTIMEOUT और CURLOPT_TIMEOUT पैरामीटर का उपयोग कर सकते हैं।

दूसरी तरफ (यह केवल काम करता है यदि आप आसान इंटरफ़ेस का उपयोग कर रहे हैं, बहु नहीं) तो सॉकेट विकल्प कॉलबैक का उपयोग करना है, जिसे आप CURLOPT_SOCKOPTFUNCTION का उपयोग कर सेट कर सकते हैं। इसमें, आपको SO_RCVTIMEO पैरामीटर के लिए setockopt() को अधिकतम कॉल करने के लिए निष्क्रिय होने से पहले निष्क्रिय होने पर अधिकतम कॉल करने के लिए कॉल करना होगा। यानी यदि पिछले 5 सेकंड में कोई बाइट प्राप्त नहीं हुआ है, तो कनेक्शन ड्रॉप करें।

संबंधित मुद्दे

 संबंधित मुद्दे