2013-02-16 37 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()嗎?

您重置它XOR清理它(在再次分配返回值curl_easy_init()之前) - 兩者都不好。欲瞭解更多信息,請參閱the documentation

+1

如果要再次使用curl_easy_reset(),請使用curl_easy_reset(),否則請使用curl_easy_cleanup()並停止使用它。 – Hermes 2014-06-06 13:20:10

11

當您使用易用的界面,對環境的libcurl,你首先要撥打:

  • curl_easy_init(),其初始化容易把手,
  • curl_global_init(),大多數情況下的標誌選項是CURL_GLOBAL_ALL

每個這樣的兩個功能在一開始被稱爲只有一次,但需要其對面的清理:

  • 當你完成curl_easy_cleanup()處理你已經聲明,
  • curl_global_cleanup()當你與libcurl中完成,

爲了獲得更好的結果檢查錯誤,你可以儘可能多的。 Libcurl爲此提供了curl_easy_strerror()函數。它返回一個描述CURLcode錯誤的字符串。此外,如果一切正常,某些函數將返回值 CURL_OK或特定的整數。

舉例來說,這裏是使用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; 
} 

如果你想重新使用手柄完全不同的目的,你最好使用不同的捲曲 容易把手。 仍然你的代碼應該工作正常,但我會使用不同的手柄,因爲它顯然是兩個獨立的操作。

但是有時候你需要用相同的處理工作,如果你不想自動做復位,使用相應的功能:

void curl_easy_reset(CURL *handle); 

注意,它不會改變活連接,會話ID緩存,DNS緩存,來自句柄的cookie和共享。

我還沒有嘗試過,但你的代碼也應該給我們類似的東西:

#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()沒有將重置您的密碼應該罰款的任何選項,你可以只改變URL像curl_easy_setoption(curl, CURLOPT_URL, <newurl>);堅持。