有什么方法可以简单地用c++发出HTTP请求吗?具体来说,我想下载一个页面(一个API)的内容,并检查内容,看看它是否包含1或0。是否也可以将内容下载到字符串中?
当前回答
有什么方法可以简单地用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;
}
其他回答
以上所有的答案都是有帮助的。我的回答只是补充了一些内容:
使用boost beast,同步示例,异步示例,ssl示例 以nghttp2为例,它支持SSL、HTTP/2 使用Facebook proxygen,这个项目包括在Facebook上使用的核心c++ HTTP抽象。它的目标是高性能和并发性。我建议用vcpkg安装它,否则你会在依赖项管理上遇到困难。支持SSL。它还支持一些高级协议:HTTP/1.1、SPDY/3、SPDY/3.1、HTTP/2和HTTP/3
nghttp2和prooxygen都是稳定的,可以考虑在生产中使用。
2020年4月的最新答案:
最近,我使用cppp -httplib(作为客户机和服务器)取得了很大的成功。它是成熟的,它的近似,单线程RPS约为6k。
更先进的是,有一个非常有前途的框架,cpv-framework,它可以在两个核上获得大约180k RPS(并且可以很好地扩展核的数量,因为它基于sestar框架,它为地球上最快的db scylladb提供动力)。
但是cpv-framework还比较不成熟;所以,对于大多数用途,我强烈推荐cppp -httplib。
这个建议取代了我之前的答案(8年前)。
虽然有点晚了。你可能更喜欢https://github.com/Taymindis/backcurl。
它允许你在移动c++开发上进行http调用。适合手机游戏开发
bcl::init(); // init when using
bcl::execute<std::string>([&](bcl::Request *req) {
bcl::setOpts(req, CURLOPT_URL , "http://www.google.com",
CURLOPT_FOLLOWLOCATION, 1L,
CURLOPT_WRITEFUNCTION, &bcl::writeContentCallback,
CURLOPT_WRITEDATA, req->dataPtr,
CURLOPT_USERAGENT, "libcurl-agent/1.0",
CURLOPT_RANGE, "0-200000"
);
}, [&](bcl::Response * resp) {
std::string ret = std::string(resp->getBody<std::string>()->c_str());
printf("Sync === %s\n", ret.c_str());
});
bcl::cleanUp(); // clean up when no more using
MS的CppRest SDK是我刚刚发现的,大约半小时后,我的第一个简单的web服务调用工作。相比之下,在这里提到的其他地方,我甚至无法安装任何东西,我不得不说,这是相当令人印象深刻的
https://github.com/microsoft/cpprestsdk
向下滚动,点击文档,然后点击入门教程,你将有一个简单的应用程序运行在任何时间。
你可以使用ACE这样做:
#include "ace/SOCK_Connector.h"
int main(int argc, ACE_TCHAR* argv[])
{
//HTTP Request Header
char* szRequest = "GET /video/nice.mp4 HTTP/1.1\r\nHost: example.com\r\n\r\n";
int ilen = strlen(szRequest);
//our buffer
char output[16*1024];
ACE_INET_Addr server (80, "example.com");
ACE_SOCK_Stream peer;
ACE_SOCK_Connector connector;
int ires = connector.connect(peer, server);
int sum = 0;
peer.send(szRequest, ilen);
while (true)
{
ACE_Time_Value timeout = ACE_Time_Value(15);
int rc = peer.recv_n(output, 16*1024, &timeout);
if (rc == -1)
{
break;
}
sum += rc;
}
peer.close();
printf("Bytes transffered: %d",sum);
return 0;
}