2013-02-16 81 views
16

मैं एक कर्ल हैंडल का सही ढंग से पुन: उपयोग करना चाहता हूं, ताकि यह मुझे त्रुटियों और सामान्य रूप से कार्य नहीं करेगा।एक कर्ल हैंडल का उचित पुन: उपयोग कैसे करें

CURL *curl; 

    curl_global_init(CURL_GLOBAL_ALL); 
    curl = curl_easy_init(); 

    curl_easy_setopt(curl, CURLOPT_USERAGENT, "Mozilla/5.0..."); 
    curl_easy_setopt(curl, CURLOPT_URL, "http://www.google.com"); 
    curl_easy_perform(curl); 

    curl_easy_setopt(curl, CURLOPT_URL, "http://www.bbc.com"); 
    curl_easy_perform(curl); 

    curl_easy_cleanup(curl); 
    curl_global_cleanup(); 

यह एक कर्ल संभाल पुन: उपयोग का एक अच्छा या सही तरीका होगा:

मान लीजिए मैं कोड के इस टुकड़े है? या मुझे उस हैंडल पर curl_easy_reset() का उपयोग करने की आवश्यकता है?

मैं भी अगर कोई सुझाव दिया है कि तुम क्या कर्ल में कर से बचना चाहिए की सराहना करेंगे। शायद कोई मुझे जानकारी के पहले से मौजूद स्रोत के लिए एक लिंक दे सकता है?

उत्तर

3

या मुझे उस हैंडल पर curl_easy_reset() का उपयोग करने की आवश्यकता है?

आप या तो इसे एक्सओआर साफ़ कर दें (curl_easy_init() के वापसी मूल्य को दोबारा निर्दिष्ट करने से पहले) - दोनों करना अच्छा नहीं है। अधिक जानकारी के लिए, the documentation देखें।

+1

अगर आप इसे फिर से उपयोग करना चाहते हैं तो curl_easy_reset() का उपयोग करें, अन्यथा curl_easy_cleanup() का उपयोग करें और इसका उपयोग बंद करें। – Hermes

11

जब आप आसान इंटरफेस पर पर्यावरण libcurl का उपयोग करें, आप पहली बार कॉल करनी होगी:

  • curl_easy_init() है, जो आसान संभाल init,
  • curl_global_init(), मामले के सबसे झंडा विकल्प हो गया है CURL_GLOBAL_ALL

उन दो कार्यों में से प्रत्येक के शुरुआत में सिर्फ एक बार फोन किया और उनके विपरीत की जरूरत है को साफ:

  • curl_easy_cleanup() जब आप समाप्त कर आप यह घोषणा करते है संभालती है,
  • curl_global_cleanup() जब आप libcurl पूरे कर चुके हैं,

बेहतर परिणामों के लिए जाँच आप कर सकते हैं जितना त्रुटियों। Libcurl उस के लिए curl_easy_strerror() समारोह प्रदान करता है। यह curlcode त्रुटि का वर्णन एक स्ट्रिंग देता है। साथ ही, कुछ फ़ंक्शन मान CURL_OK या सबकुछ ठीक होने पर एक विशिष्ट पूर्णांक लौटाते हैं।

#include <curl.h> 

int main(void) 
{ 
    /* declaration of an object CURL */ 
    CURL *handle;     

    /* result of the whole process */ 
    CURLcode result;    

    /* the first functions */ 
    /* set up the program environment that libcurl needs */ 
    curl_global_init(CURL_GLOBAL_ALL); 
    /* curl_easy_init() returns a CURL easy handle that you're gonna reuse in other easy functions*/ 
    handle = curl_easy_init(); 



    /* if everything's all right with the easy handle... */ 
    if(handle) 
    { 
      /* ...you can list the easy functions */ 
      /* here we just gonna try to get the source code of http://example.com */ 
      curl_easy_setopt(handle, CURLOPT_URL, "http://example.com"); 

      /* but in that case we also tell libcurl to follow redirection */ 
      curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1L); 

      /* perform, then store the expected code in 'result'*/ 
      result = curl_easy_perform(handle); 

      /* Check for errors */ 
      if(result != CURLE_OK) 
      { 
        /* if errors have occured, tell us wath's wrong with 'result'*/ 
        fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(result)); 

        return 1; 
      } 
    } 
    /* if something's gone wrong with curl at the beginning, we'll appriciate that piece of code */ 
    else 
    { 
      fprintf(stderr, "Curl init failed!\n"); 

      return 1; 
    } 

    /* cleanup since you've used curl_easy_init */ 
    curl_easy_cleanup(handle); 

    /* this function releases resources acquired by curl_global_init() */ 
    curl_global_cleanup(); 

    /* make the programme stopping for avoiding the console closing befor you can see anything */ 
    system("PAUSE"); 

    return 0; 
} 

आप एक पूरी तरह से अलग उद्देश्य के लिए है कि हैंडल का पुन: उपयोग करना चाहते हैं तो आप बेहतर अलग कर्ल आसान हैंडल का उपयोग करेंगे:

उदाहरण के लिए, यहाँ CURLOPT_URL विकल्प का उपयोग करने के लिए उचित तरीका है। फिर भी आपका कोड ठीक काम करना चाहिए लेकिन मैं अलग-अलग हैंडल का उपयोग करता हूं क्योंकि यह स्पष्ट रूप से दो अलग-अलग संचालन है।

हालांकि कभी कभी आप एक ही संभाल के साथ काम करने के लिए, उचित कार्य का उपयोग की आवश्यकता होगी और यदि आप नहीं करते हैं तो उसे रीसेट करने के लिए स्वचालित रूप से हैं:

void curl_easy_reset(CURL *handle); 

ध्यान दें कि यह लाइव कनेक्शन नहीं बदलता है, सत्र आईडी कैश, DNS कैश, हैंडल से कुकीज़ और शेयर।

मैं इसे करने की कोशिश नहीं की है, लेकिन अपने कोड के साथ यह हमें ऐसा ही कुछ देना चाहिए:

#include <curl.h> 

int main(void) 
{ 
    CURL *handle;     
    CURLcode result; 

    int error = 0; 
    int error2 = 0;    

    curl_global_init(CURL_GLOBAL_ALL); 
    handle = curl_easy_init(); 

    if(handle) 
    { 
      curl_easy_setopt(handle, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 6.1; fr; rv:1.9.2) Gecko/20100115 Firefox/3.6"); 
      curl_easy_setopt(handle, CURLOPT_URL, "http://www.google.com"); 
      result = curl_easy_perform(handle); 

      if(result != CURLE_OK) 
      { 
        fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(result)); 

        error++; 
      } 

      Sleep(5000);   // make a pause if you working on console application 

      curl_easy_reset(handle); 

      curl_easy_setopt(handle, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 6.1; fr; rv:1.9.2) Gecko/20100115 Firefox/3.6");  // have to write it again 
      curl_easy_setopt(handle, CURLOPT_URL, "http://www.bbc.com"); 
      result = curl_easy_perform(handle); 

      if(result != CURLE_OK) 
      { 
        fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(result)); 

        error2++; 
      } 

      if(error == 1 || error2 == 1) 
      { 
        return 1; 
      } 
    } 
    else 
    { 
      fprintf(stderr, "Curl init failed!\n"); 

      return 1; 
    } 

    curl_easy_cleanup(handle); 
    curl_global_cleanup(); 

    system("PAUSE"); 

    return 0; 
} 

आप Sleep के साथ किसी भी समस्या है, तो sleep या _sleep द्वारा इसे बदलना कोशिश या 5 से 5000 की जगह

4

यदि मैं सही तरीके से प्रश्न समझता हूं तो आप जानना चाहेंगे कि क्या आप curl_easy_perform() पर कॉल कर सकते हैं और फिर केवल curl_easy_setoption() के माध्यम से यूआरएल बदल सकते हैं और फिर दूसरा कॉल कर सकते हैं? यह किसी भी त्रुटि के बिना काम करना चाहिए क्योंकि फ़ंक्शन हैंडल के लिए पहले सेट विकल्पों को नहीं बदलता है। यह एक छोटा काम कर उदाहरण है:

size_t writeCallback(char* contents, size_t size, size_t nmemb, std::string* buffer) { 
    size_t realsize = size * nmemb; 
    if(buffer == NULL) { 
    return 0; 
    } 
    buffer->append(contents, realsize); 
    return realsize; 
} 

int main(int argc, char** argv) { 
    std::string buffer; 
    // initialize global 
    curl_global_init(CURL_GLOBAL_ALL); 
    // start a libcurl easy session 
    CURL* ch = curl_easy_init(); 
    // this options will only be set once 
    curl_easy_setopt(ch, CURLOPT_VERBOSE, 0); 
    curl_easy_setopt(ch, CURLOPT_FOLLOWLOCATION, 1); 
    curl_easy_setopt(ch, CURLOPT_USERAGENT, "Crawler"); 
    curl_easy_setopt(ch, CURLOPT_WRITEFUNCTION, &writeCallback); 
    curl_easy_setopt(ch, CURLOPT_WRITEDATA, &buffer); 

    std::vector<const char*> queue; 
    queue.push_back("http://www.google.com"); 
    queue.push_back("http://www.stackoverflow.com"); 

    const char* url; 
    CURLcode code; 

    do { 
     // grab an url from the queue 
     url = queue.back(); 
     queue.pop_back(); 
     // only change this option for the handle 
     // the rest will stay intact 
     curl_easy_setopt(ch, CURLOPT_URL, url); 
     // perform transfer 
     code = curl_easy_perform(ch); 
     // check if everything went fine 
     if(code != CURLE_OK) { 

     } 
     // clear the buffer 
     buffer.clear(); 
    } while(queue.size() > 0); 
    // cleanup 
    curl_easy_cleanup(ch); 
    curl_global_cleanup(); 

    return 0; 
} 

या मैं कि संभाल पर curl_easy_reset() का उपयोग करने की आवश्यकता है?

जवाब है कोईcurl_easy_perform() के बाद से किसी भी विकल्प के लिए अपने कोड ठीक किया जाना चाहिए नहीं रीसेट कर देगा और आप केवल curl_easy_setoption(curl, CURLOPT_URL, <newurl>); तरह यूआरएल को बदलने के साथ छड़ी कर सकते हैं।