Intereting Posts
наилучшая практика для предоставления C API-функций, скрывающих внутренние функции pipe, fork, как возможно, что программа запускает if и else того же условия Программирование сокета для начинающих в C Что происходит, когда два процесса записываются в одну и ту же часть mmaped-файла? Почему все файлы C, написанные моим преподавателем, начинаются с #? Проверка границы при обработке изображений libpcap – длина пакета IP-пакета равна нулю байтов с запросами tcp loopback Проблема Yacc: Сделать данные доступными в следующем Non Terminal Установите прецизионные и зацепляющие нули, но никогда не печатайте экспоненту Что делает следующий код? Безопасно ли использовать массивы переменной длины? While ((c = getc (файл))! = EOF) цикл не прекратит выполнение Соглашение об именах в Objective C / C начинается с «_»? Разница между использованием указателя и массива с нулевыми элементами в структурах C fscanf входная проверка

как правильно использовать ручку завитка

Я хочу правильно использовать ручку завитка, чтобы он не дал мне ошибок и нормально функционировал.

Предположим, у меня есть эта часть кода:

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() для этого дескриптора?

Я был бы также признателен, если бы кто-нибудь предложил, что вам следует избегать делать с завитом. Может быть, кто-то может дать мне ссылку на уже существующий источник информации?

Когда вы используете среду 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  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); 

Обратите внимание, что он не изменяет живые подключения, кеш идентификатора сеанса, кеш DNS, cookies и общие ресурсы из дескриптора.

Я не пробовал, но с вашим кодом он должен дать нам что-то вроде этого:

 #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() а затем изменить URL-адрес через 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 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, ); ,

Или мне нужно использовать curl_easy_reset () для этого дескриптора?

Вы либо перезагрузите его, либо очистите его (перед тем как присвоить возвращаемое значение curl_easy_init() снова) – делать это нехорошо. Для получения дополнительной информации см. Документацию .