2013-02-16 21 views
16

Voglio riutilizzare correttamente una maniglia di arricciatura, in modo che non mi dia errori e funzioni normalmente.come riutilizzare correttamente una maniglia di arricciatura

Supponiamo che io ho questo pezzo di codice:

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(); 

Questo sarebbe un modo buono o corretto di riutilizzo di un manico ricciolo? O devo usare curl_easy_reset() su quella maniglia?

Vorrei anche sapere se qualcuno ha suggerito cosa si dovrebbe evitare di fare in curl. Forse qualcuno potrebbe darmi un link ad una fonte di informazioni già esistente?

risposta

3

Oppure ho bisogno di usare curl_easy_reset() su quella maniglia?

Tu o ripristinare lo si XOR Clean Up (prima di assegnare nuovamente il valore di ritorno di curl_easy_init()) - facendo entrambi non è buono. Per maggiori informazioni, vedi the documentation.

+1

Usa curl_easy_reset() se vuoi usarlo di nuovo, altrimenti usa curl_easy_cleanup() e smetti di usarlo. – Hermes

11

Quando si utilizza il libcurl ambiente sull'interfaccia semplice, dovete prima di chiamare:

  • curl_easy_init(), che init la maniglia facile,
  • curl_global_init(), la maggior parte del caso l'opzione di bandiera deve essere CURL_GLOBAL_ALL

Ognuna di queste due funzioni è chiamato solo una volta all'inizio e hanno bisogno di loro opposto ripulire:

  • curl_easy_cleanup() quando hai finito di maniglie hai dichiarare,
  • curl_global_cleanup() quando hai finito con libcurl,

Per ottenere risultati migliori controllare gli errori per quanto è possibile. Libcurl fornisce la funzione curl_easy_strerror() per quello. Restituisce una stringa che descrive l'errore CURLcode. Inoltre, alcune funzioni restituiscono il valore CURL_OK o un numero intero specifico se tutto è OK.

Per esempio, ecco il modo corretto di utilizzare l'opzione CURLOPT_URL:

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

Se si vuole riutilizzare quella maniglia per uno scopo totalmente diverso è meglio utilizzare diverse CURL semplici maniglie. Ancora il tuo codice dovrebbe funzionare bene ma userei maniglie diverse perché ovviamente sono due operazioni separate.

Tuttavia a volte avrete bisogno di lavorare con la stessa maniglia e se non si vuole fare ripristinarla automaticamente, utilizzare l'apposita funzione:

void curl_easy_reset(CURL *handle); 

Si noti che non cambia collegamenti in diretta, la cache ID sessione, la cache DNS, i cookie e le condivisioni dall'handle.

Non ho provato, ma con il codice che ci dovrebbe dare qualcosa di simile:

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

Se avete qualche problema con Sleep, provate a sostituirlo con sleep o _sleep o sostituire 5000 da 5

4

Se ho letto correttamente la domanda, vorrebbe sapere se è possibile effettuare una chiamata a curl_easy_perform() e quindi modificare l'URL solo tramite curl_easy_setoption() e quindi effettuare una seconda chiamata? Questo dovrebbe funzionare senza errori poiché la funzione non modifica le opzioni precedentemente impostate per l'handle. Questo è un esempio di lavoro di breve:

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

o devo usare curl_easy_reset() su quel manico?

La risposta è non dal curl_easy_perform() non reimpostare le opzioni il codice dovrebbe essere fine e si può attaccare con solo cambiando l'url come curl_easy_setoption(curl, CURLOPT_URL, <newurl>);.