微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C++ libcurl:使用非阻塞循环检测 HTTP 状态码变化

如何解决C++ libcurl:使用非阻塞循环检测 HTTP 状态码变化

场景:

在预定时间更新之前,网页的 HTTP status code503。在预定时间之后将新数据添加页面时,HTTP status code 将更改为 200

目标:

使用非阻塞循环,尽可能快地检测HTTP status code503200的这种变化 >.通过下面的当前代码WHILE 循环成功侦听 HTTP status code 中的更改并打印出成功语句。一旦检测到 200,break 语句将停止循环。

但是,似乎程序每次发出 HTTP 请求时都必须等待响应之前移动到下一个 WHILE 循环迭代,表现为 阻塞 方式。

问题:

使用 libcurl C++,如何修改以下程序以传输请求(到单个 URL)以检测 HTTP status code 更改,而无需在发送另一个请求之前等待响应?

请注意:我知道过多的请求可能会被视为不友好(这是我自己的 URL 的实验)。

在发布此问题之前,已咨询以下 SO 问题和资源:

到目前为止的尝试:

  • 使用多线程和 FOR 中的 C 循环重复调用函数来检测 HTTP 代码更改,具有轻微的延迟优势。请参阅此处的代码https://pastebin.com/73dBwkq3
  • 再次使用 OpenMP,当使用 FOR 循环而不是原始的 WHILE 循环时。延迟优势并不明显。
  • 使用 libcurl 文档 C 教程尝试复制一个程序,该程序只侦听一个 URL 的更改,但使用 asynchronous multi-interface 有困难。

当前尝试使用 curl_easy_opt:

#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <curl/curl.h>

// Function for writing callback
size_t write_callback(char *ptr,size_t size,size_t nmemb,void *userdata) {

        std::vector<char> *response = reinterpret_cast<std::vector<char> *>(userdata);
        response->insert(response->end(),ptr,ptr+nmemb);
        return nmemb;
}

long request(CURL *curl,const std::string &url) {

        std::vector<char> response;
        long response_code;

        curl_easy_setopt(curl,CURLOPT_URL,url.c_str());
        curl_easy_getinfo(curl,CURLINFO_RESPONSE_CODE,&response_code);
        curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,write_callback);
        curl_easy_setopt(curl,CURLOPT_WRITEDATA,&response);

        auto res = curl_easy_perform(curl);

        if (response_code == 200) {
                std::cout << "SUCCESS" << std::endl;
        }

        return response_code;
}

int main() {
    curl_global_init(CURL_GLOBAL_ALL);
        CURL *curl = curl_easy_init();

       while (true) {
               long response_code = request(curl,"www.example.com");
               if (response_code == 200) {
                       break; // Page updated
               }
       }

        curl_easy_cleanup(curl);
        curl_global_cleanup();
    return 0;
}

总结:

使用 C++libcurl,有谁知道如何使用 WHILE 循环向一个 URL 重复发送请求,而不必等待发送请求之间的响应?这样做的目的是尽快检测到变化。

我知道有大量的 libcurl 文档,但在掌握多界面方面以帮助将其应用于此问题时遇到了困难。

解决方法

/* get us the resource without a body - use HEAD! */
curl_easy_setopt(curl,CURLOPT_NOBODY,1L);

如果 HEAD 对您不起作用,服务器可能会拒绝 HEAD,另一种解决方案:

size_t header_callback(char *buffer,size_t size,size_t nitems,void *userdata) {
  long response_code = 0;
  curl_easy_getinfo(curl,CURLINFO_RESPONSE_CODE,&response_code);
  if (response_code != 200)
    return 0;  // Aborts the request.
  return nitems;
}

curl_easy_setopt(curl,CURLOPT_HEADERFUNCTION,header_callback);

第二种方案会消耗网络流量,HEAD好很多,收到200后就可以请求GET了。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。