如何正确重用curl手柄

我想正确地重用一个curl句柄,这样它就不会给我错误和正常的function。

假设我有这段代码:

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手柄的好方法吗? 或者我需要在该句柄上使用curl_easy_reset()吗?

我也很感激,如果有人建议你应该避免curl。 也许有人可以给我一个已经存在的信息来源的链接?

在easy界面上使用环境libcurl时,首先必须调用:

  • curl_easy_init() ,初始化容易,
  • curl_global_init() ,大多数情况下flag选项必须是CURL_GLOBAL_ALL

这两个函数中的每一个在开始时只调用一次,需要相反的清理:

  • curl_easy_cleanup()当你完成你已声明的句柄时,
  • 当你完成libcurl时curl_global_cleanup()

为了获得更好的结果,请尽可能多地检查错误。 Libcurl为此提供了curl_easy_strerror()函数。 它返回一个描述CURLcode错误的字符串。 此外,如果一切正常,某些函数会返回值CURL_OK或特定的整数。

例如,以下是使用CURLOPT_URL选项的正确方法:

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

如果你想为了完全不同的目的重用那个句柄,你最好使用不同的CURL简易句柄。 仍然你的代码应该工作正常,但我会使用不同的句柄,因为它显然是两个单独的操作。

但是,有时您需要使用相同的句柄,如果您不想自动重置它,请使用适当的函数:

 void curl_easy_reset(CURL *handle); 

请注意,它不会更改实时连接,会话ID缓存,DNS缓存,cookie和句柄中的共享。

我没有尝试过但是你的代码应该给我们这样的东西:

 #include  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替换它或将5000替换为5。

如果我正确理解了这个问题,你想知道你是否可以调用curl_easy_perform() ,然后只通过curl_easy_setoption()更改url,然后再拨打第二个电话? 这应该没有任何错误,因为该函数不会更改任何先前设置的句柄选项。 这是一个简短的工作示例:

 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 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, );的url curl_easy_setoption(curl, CURLOPT_URL, );

或者我需要在该句柄上使用curl_easy_reset()吗?

你要么重置它XOR清理它(再次分配curl_easy_init()的返回值之前) – 两者都做不好。 有关详细信息,请参阅文档 。