有什么方法可以简单地用c++发出HTTP请求吗?具体来说,我想下载一个页面(一个API)的内容,并检查内容,看看它是否包含1或0。是否也可以将内容下载到字符串中?


当前回答

如果您正在寻找在多个平台(Linux, Windows和Mac)支持的c++中的HTTP客户端库,以使用Restful web服务。您可以有以下选项。

QT网络库-允许应用程序发送网络请求并接收回复 c++ REST SDK -一个新兴的支持PPL的第三方HTTP库 Libcurl -它可能是本地世界中使用最多的http库之一。

其他回答

libCURL是一个非常好的选择。根据你需要做什么,教程应该告诉你你想要什么,特别是简单的操作。但是,基本上,你可以这样做只是为了查看页面的源代码:

CURL* c;
c = curl_easy_init();
curl_easy_setopt( c, CURL_URL, "www.google.com" );
curl_easy_perform( c );
curl_easy_cleanup( c );

我相信这将导致结果被打印到标准输出。如果您想要处理它——我假设您是这样做的——您需要设置CURL_WRITEFUNCTION。上面链接的curl教程中介绍了所有这些内容。

c++没有提供任何直接实现它的方法。这完全取决于你拥有什么样的平台和库。

在最坏的情况下,您可以使用boost::asio库来建立TCP连接,发送HTTP报头(RFC 2616),并直接解析响应。查看您的应用程序需求,这很简单。

有什么方法可以简单地用c++发出HTTP请求吗?具体来说,我想下载一个页面(一个API)的内容,并检查内容,看看它是否包含1或0。是否也可以将内容下载到字符串中?

首先……我知道这个问题已经有12年了。然而。没有一个答案给出的例子是“简单的”,不需要构建一些外部库

下面是我能想到的检索和打印网页内容的最简单的解决方案。

关于下面示例中使用的函数的一些文档

// wininet lib : https://learn.microsoft.com/en-us/windows/win32/api/wininet/ // wininet->internetopena(); https://learn.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-internetopena // wininet->intenetopenurla(); https://learn.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-internetopenurla // wininet->internetreadfile(); https://learn.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-internetreadfile // wininet->internetclosehandle(); https://learn.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-internetclosehandle

#include <iostream>

#include <WinSock2.h>
#include <wininet.h>
#pragma comment(lib, "wininet.lib")

int main()
{
    //  ESTABLISH SOME LOOSE VARIABLES
    const int size = 4096;
    char buf[size];
    DWORD length;

    //  ESTABLISH CONNECTION TO THE INTERNET
    HINTERNET internet = InternetOpenA("Mozilla/5.0", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, NULL);
    if (!internet)
        ExitProcess(EXIT_FAILURE);  //  Failed to establish connection to internet, Exit

    //  ATTEMPT TO CONNECT TO WEBSITE "google.com"
    HINTERNET response = InternetOpenUrlA(internet, "http://www.google.com", NULL, NULL, NULL, NULL);
    if (!response) {
        //  CONNECTION TO "google.com" FAILED
        InternetCloseHandle(internet);  //  Close handle to internet
        ExitProcess(EXIT_FAILURE);
    }

    //  READ CONTENTS OF WEBPAGE IN HTML FORMAT
    if (!InternetReadFile(response, buf, size, &length)) {     
        //  FAILED TO READ CONTENTS OF WEBPAGE
        //  Close handles and Exit
        InternetCloseHandle(response);                      //  Close handle to response
        InternetCloseHandle(internet);                      //  Close handle to internet
        ExitProcess(EXIT_FAILURE);
    }
    
    //  CLOSE HANDLES AND OUTPUT CONTENTS OF WEBPAGE
    InternetCloseHandle(response);                      //  Close handle to response
    InternetCloseHandle(internet);                      //  Close handle to internet
    std::cout << buf << std::endl;
    return 0;
}

2020年4月的最新答案:

最近,我使用cppp -httplib(作为客户机和服务器)取得了很大的成功。它是成熟的,它的近似,单线程RPS约为6k。

更先进的是,有一个非常有前途的框架,cpv-framework,它可以在两个核上获得大约180k RPS(并且可以很好地扩展核的数量,因为它基于sestar框架,它为地球上最快的db scylladb提供动力)。

但是cpv-framework还比较不成熟;所以,对于大多数用途,我强烈推荐cppp -httplib。

这个建议取代了我之前的答案(8年前)。

下面是一些(相对)简单的c++ 11代码,使用libCURL将URL的内容下载到std::vector<char>:

http_download.hh

# pragma once

#include <string>
#include <vector>

std::vector<char> download(std::string url, long* responseCode = nullptr);

http_download.cc

#include "http_download.hh"

#include <curl/curl.h>
#include <sstream>
#include <stdexcept>

using namespace std;

size_t callback(void* contents, size_t size, size_t nmemb, void* user)
{
  auto chunk = reinterpret_cast<char*>(contents);
  auto buffer = reinterpret_cast<vector<char>*>(user);

  size_t priorSize = buffer->size();
  size_t sizeIncrease = size * nmemb;

  buffer->resize(priorSize + sizeIncrease);
  std::copy(chunk, chunk + sizeIncrease, buffer->data() + priorSize);

  return sizeIncrease;
}

vector<char> download(string url, long* responseCode)
{
  vector<char> data;

  curl_global_init(CURL_GLOBAL_ALL);
  CURL* handle = curl_easy_init();
  curl_easy_setopt(handle, CURLOPT_URL, url.c_str());
  curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, callback);
  curl_easy_setopt(handle, CURLOPT_WRITEDATA, &data);
  curl_easy_setopt(handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
  CURLcode result = curl_easy_perform(handle);
  if (responseCode != nullptr)
    curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, responseCode);
  curl_easy_cleanup(handle);
  curl_global_cleanup();

  if (result != CURLE_OK)
  {
    stringstream err;
    err << "Error downloading from URL \"" << url << "\": " << curl_easy_strerror(result);
    throw runtime_error(err.str());
  }

  return data;
}