im尝试使用curl多接口连续循环。我有一个计时器功能,需要一次连续地循环遍历4个网址,然后转到下一个4个网址,依此类推。等等。我已经成功地使curl轮询了我的手柄的状态,但是当手柄达到0时,我尝试使用新网址将curl句柄重置为再次循环,但无法正常工作。我的计时器功能保持应有的工作,但是curl多次停止,并使用相同的4个URL给我相同的curl响应,即使我每次都尝试重置手柄。请对此提供任何帮助,谢谢。.下面是我的代码的片段。
// Timer function that fires every 30 seconds with 4 different URL's each time
void timerFunction (QString url1,QString url2,QString url3,QString url4)
{
CURLMsg *msg = NULL;
std::string url1_ = url1.toStdString();
std::string url2_ = url2.toStdString();
std::string url3_ = url3.toStdString();
std::string url4_ = url4.toStdString();
CURLM *curlm;
int handle_count;
curlm = curl_multi_init();
CURL *curl1 = NULL;
curl1 = curl_easy_init();
CURL *curl2 = NULL;
curl2 = curl_easy_init();
CURL *curl3 = NULL;
curl3 = curl_easy_init();
CURL *curl4 = NULL;
curl4 = curl_easy_init();
if(curl1 && curl2 && curl3 && curl4)
{
curl_easy_setopt(curl1, CURLOPT_URL, url1_.c_str());
curl_easy_setopt(curl1, CURLOPT_WRITEFUNCTION, writeCallback);
curl_multi_add_handle(curlm, curl1);
curl_easy_setopt(curl2, CURLOPT_URL, url2_.c_str());
curl_easy_setopt(curl2, CURLOPT_WRITEFUNCTION, writeCallback);
curl_multi_add_handle(curlm, curl2);
curl_easy_setopt(curl3, CURLOPT_URL, url3_.c_str());
curl_easy_setopt(curl3, CURLOPT_WRITEFUNCTION, writeCallback);
curl_multi_add_handle(curlm, curl3);
curl_easy_setopt(curl4, CURLOPT_URL, url4_.c_str());
curl_easy_setopt(curl4, CURLOPT_WRITEFUNCTION, writeCallback);
curl_multi_add_handle(curlm, curl4);
CURLMcode code;
while(1)
{
code = curl_multi_perform(curlm, &handle_count);
if(handle_count == 0)
{
qDebug() << "Handle is 0, CURL Processing is done -- Repeat Process ";
break;
}
while ((msg = curl_multi_info_read(curlm, &handle_count)))
{
if (msg->msg == CURLMSG_DONE)
{
qDebug() << msg->msg;
curl_easy_reset(curl1);
curl_easy_reset(curl2);
curl_easy_reset(curl3);
curl_easy_reset(curl4);
handle_count = 4;
code = curl_multi_perform(curlm, &handle_count);
}
}
}
}
答案 0 :(得分:1)
curl_easy_reset明确指出:
重新初始化先前在指定的CURL句柄上设置的所有选项 设为默认值。这会将手柄恢复为与 刚好是用curl_easy_init创建的。
它不会更改句柄中保存的以下信息:实时 连接,会话ID缓存,DNS缓存,Cookie和 股票。
您需要做的是,在完成响应后,对循环中的每个句柄使用curl_multi_remove_handle,然后使用curl_easy_cleanup。
但是,您还需要在循环后使用curl_multi_cleanup来删除所有句柄。
您的代码如下:
// Timer function that fires every 30 seconds with 4 different URL's each time
void timerFunction (QString url1,QString url2,QString url3,QString url4)
{
CURLMsg *msg = NULL;
std::string url1_ = url1.toStdString();
std::string url2_ = url2.toStdString();
std::string url3_ = url3.toStdString();
std::string url4_ = url4.toStdString();
CURLM *curlm;
CURL* eh = NULL;
int still_running = 0, i = 0, msgs_left = 0;
curlm = curl_multi_init();
CURL *curl1 = NULL;
curl1 = curl_easy_init();
CURL *curl2 = NULL;
curl2 = curl_easy_init();
CURL *curl3 = NULL;
curl3 = curl_easy_init();
CURL *curl4 = NULL;
curl4 = curl_easy_init();
if(curl1 && curl2 && curl3 && curl4)
{
curl_easy_setopt(curl1, CURLOPT_URL, url1_.c_str());
curl_easy_setopt(curl1, CURLOPT_WRITEFUNCTION, writeCallback);
curl_multi_add_handle(curlm, curl1);
curl_easy_setopt(curl2, CURLOPT_URL, url2_.c_str());
curl_easy_setopt(curl2, CURLOPT_WRITEFUNCTION, writeCallback);
curl_multi_add_handle(curlm, curl2);
curl_easy_setopt(curl3, CURLOPT_URL, url3_.c_str());
curl_easy_setopt(curl3, CURLOPT_WRITEFUNCTION, writeCallback);
curl_multi_add_handle(curlm, curl3);
curl_easy_setopt(curl4, CURLOPT_URL, url4_.c_str());
curl_easy_setopt(curl4, CURLOPT_WRITEFUNCTION, writeCallback);
curl_multi_add_handle(curlm, curl4);
while(1)
{
curl_multi_perform(curlm, &still_running);
do {
int numfds = 0;
CURLMcode res = curl_multi_wait(curlm, NULL, 0, MAX_WAIT_MSECS, &numfds);
if (res != CURLM_OK) {
// handle error your way
}
curl_multi_perform(curlm, &still_running);
} while (still_running);
while ((msg = curl_multi_info_read(curlm, &msgs_left)))
{
if (msg->msg == CURLMSG_DONE)
{
eh = msg->easy_handle;
qDebug() << msg->msg;
curl_multi_remove_handle(curlm, eh);
curl_easy_cleanup(eh);
}
}
curl_multi_cleanup(cm);
}
}
尚未测试您的代码,但我对其进行了修改,以便您了解应如何做。